Page MenuHomec4science

No OneTemporary

File Metadata

Created
Wed, Apr 24, 08:53
This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 109ec76f3..9694833db 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,186 +1,188 @@
#===============================================================================
# @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: Mon Sep 15 2014
+# @date last modification: Thu Nov 19 2015
#
# @brief main configuration file
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 2.8.12)
# 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 AkantuLibraryDepends)
endif()
include(CMakeVersionGenerator)
include(CMakePackagesSystem)
include(CMakeFlagsHandling)
include(AkantuPackagesSystem)
include(AkantuMacros)
#cmake_activate_debug_message()
#===============================================================================
# Version Number
#===============================================================================
# AKANTU version number. An even minor number corresponds to releases.
set(AKANTU_MAJOR_VERSION 2)
set(AKANTU_MINOR_VERSION 3)
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")
#Profiling
set(CMAKE_CXX_FLAGS_PROFILING "-g -pg -DNDEBUG -DAKANTU_NDEBUG -O2"
CACHE STRING "Flags used by the compiler during profiling builds")
set(CMAKE_C_FLAGS_PROFILING "-g -pg -DNDEBUG -DAKANTU_NDEBUG -O2"
CACHE STRING "Flags used by the compiler during profiling builds")
set(CMAKE_Fortran_FLAGS_PROFILING "-g -pg -DNDEBUG -DAKANTU_NDEBUG -O2"
CACHE STRING "Flags used by the compiler during profiling builds")
set(CMAKE_EXE_LINKER_FLAGS_PROFILING "-pg"
CACHE STRING "Flags used by the linker during profiling builds")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-pg"
CACHE STRING "Flags used by the linker during profiling builds")
mark_as_advanced(
CMAKE_CXX_FLAGS_PROFILING
CMAKE_C_FLAGS_PROFILING
CMAKE_Fortran_FLAGS_PROFILING
CMAKE_EXE_LINKER_FLAGS_PROFILING
CMAKE_SHARED_LINKER_FLAGS_PROFILING
)
include(CMakeDetermineCCompiler)
#===============================================================================
# Dependencies
#===============================================================================
declare_akantu_types()
package_list_packages(${PROJECT_SOURCE_DIR}/packages
EXTRA_PACKAGES_FOLDER ${PROJECT_SOURCE_DIR}/extra_packages)
## 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
#===============================================================================
option(AKANTU_EXAMPLES "Activate examples" OFF)
option(AKANTU_TESTS "Activate tests" OFF)
include(AkantuTestsMacros)
include(AkantuExamplesMacros)
if(AKANTU_EXAMPLES OR AKANTU_TESTS)
option(AKANTU_BUILD_ALL_EXAMPLES "Build all examples")
option(AKANTU_BUILD_ALL_TESTS "Build all tests")
find_package(GMSH REQUIRED)
endif()
if(AKANTU_EXAMPLES)
add_subdirectory(examples)
endif()
add_test_tree(test)
#===============================================================================
# Install and Packaging
#===============================================================================
include(AkantuInstall)
if(NOT AKANTU_DISABLE_CPACK)
include(AkantuCPack)
endif()
#===============================================================================
# Install and Packaging
#===============================================================================
package_is_activated(python_interface _python_act)
if(_python_act)
add_subdirectory(python)
# add_subdirectory(akantu4py)
endif()
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
index 6e644b4d9..23185704b 100644
--- a/CTestConfig.cmake
+++ b/CTestConfig.cmake
@@ -1,44 +1,45 @@
#===============================================================================
# @file CTestConfig.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Thu Jan 06 2011
-# @date last modification: Thu Aug 21 2014
+# @date last modification: Sun Oct 19 2014
#
# @brief configuration for ctest
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
## This file should be placed in the root directory of your project.
## Then modify the CMakeLists.txt file in the root directory of your
## project to incorporate the testing dashboard.
## # The following are required to uses Dart and the Cdash dashboard
## ENABLE_TESTING()
## INCLUDE(CTest)
set(CTEST_PROJECT_NAME "Akantu")
set(CTEST_NIGHTLY_START_TIME "06:10:00 EST")
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "lsmssrv1.epfl.ch")
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Akantu")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/cmake/AkantuBuildTreeSettings.cmake.in b/cmake/AkantuBuildTreeSettings.cmake.in
index fe20feff6..0fddeb0ab 100644
--- a/cmake/AkantuBuildTreeSettings.cmake.in
+++ b/cmake/AkantuBuildTreeSettings.cmake.in
@@ -1,35 +1,37 @@
#===============================================================================
# @file AkantuBuildTreeSettings.cmake.in
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Thu Dec 01 18:00:05 2011
+# @date creation: Thu Dec 01 2011
+# @date last modification: Sun Oct 19 2014
#
# @brief Configuration for link with build tree
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
set(AKANTU_INCLUDE_DIR
"@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
diff --git a/cmake/AkantuCPack.cmake b/cmake/AkantuCPack.cmake
index 952fbf0f2..7419d6dd3 100644
--- a/cmake/AkantuCPack.cmake
+++ b/cmake/AkantuCPack.cmake
@@ -1,121 +1,122 @@
#===============================================================================
# @file AkantuCPack.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Wed Oct 17 2012
-# @date last modification: Tue May 13 2014
+# @date last modification: Thu Nov 12 2015
#
# @brief Configure the packaging system
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
set(PACKAGE_FILE_NAME "akantu" CACHE STRING "Name of package to be generated")
mark_as_advanced(PACKAGE_FILE_NAME)
#set(CPACK_GENERATOR "DEB;TGZ;TBZ2;STGZ;RPM")
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(CPACK_GENERATOR "TGZ")
else()
set(CPACK_GENERATOR "TGZ;NSIS")
package_get_all_external_informations(
_external_include_dirs
_external_libraries
)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${_external_libraries})
include(InstallRequiredSystemLibraries)
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "i.86" OR CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "[aA][mM][dD]64")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_arch "amd64")
else()
set(_arch "i386")
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc")
set(_arch "powerpc")
else()
set(_arch "unknown")
endif()
if(WIN32 AND MINGW)
set(_arch "mingw32")
endif()
# General configuration
set(CPACK_PACKAGE_VENDOR "LSMS")
set(CPACK_PACKAGE_FILE_NAME "${PACKAGE_FILE_NAME}-${AKANTU_VERSION}-${_arch}")
set(CPACK_PACKAGE_VERSION "${AKANTU_VERSION}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A multipurpose finite element library, Akantu")
set(CPACK_PACKAGE_NAME "akantu")
#set(CMAKE_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/akantu.ico")
# Debian config package
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "nicolas.richart@epfl.ch, guillaume.anciaux@epfl.ch")
set(CPACK_DEBIAN_PACKAGE_SECTION "Science")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${_arch}" CACHE STRING "Architecture of akantu's package")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${${_project}_PACKAGE_SYSTEM_DEBIAN_PACKAGE_DEPENDS}")
mark_as_advanced(CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
# RPM package configuration
#set(CPACK_RPM_PACKAGE_REQUIRES "${${_project}_PACKAGE_SYSTEM_DEBIAN_PACKAGE_DEPENDS}")
# NSIS Windows installer
#set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/akantu.ico")
#set(CPACK_NSIS_CONTACT "akantu@akantu.ch")
#set(CPACK_NSIS_MODIFY_PATH ON)
# Components description
set(CPACK_COMPONENTS_ALL lib dev bin python)
set(CPACK_COMPONENT_LIB_DISPLAY_NAME "Libraries")
set(CPACK_COMPONENT_BIN_DISPLAY_NAME "Examples")
set(CPACK_COMPONENT_PYTHON_DISPLAY_NAME "Python interface")
set(CPACK_COMPONENT_DEV_DISPLAY_NAME "C++ Headers")
set(CPACK_COMPONENT_DEV_DEPENDS lib)
set(CPACK_COMPONENT_BIN_DEPENDS lib)
set(CPACK_COMPONENT_PYTHON_DEPENDS lib)
set(CPACK_COMPONENT_LIB_DESCRIPTION
"Akantu libraries")
set(CPACK_COMPONENT_DEV_DESCRIPTION
"Akantu C/C++ header files")
set(CPACK_COMPONENT_LIB_GROUP "Akantu Libraries and Executables")
set(CPACK_COMPONENT_BIN_GROUP "Akantu Libraries and Executables")
set(CPACK_COMPONENT_PYTHON_GROUP "Akantu Libraries and Executables")
set(CPACK_COMPONENT_DEV_GROUP "Development")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PACKAGE_FILE_NAME}-${AKANTU_VERSION}-src")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
string(TOUPPER ${PROJECT_NAME} _project)
unset(CPACK_SOURCE_IGNORE_FILES)
package_get_all_deactivated_packages(_deactivated_packages)
foreach(_pkg ${_deactivated_packages}})
_package_get_filename(${_pkg} _file_name)
list(APPEND CPACK_SOURCE_IGNORE_FILES ${_file_name})
_package_get_source_files(${_pkg} _srcs _pub_hdrs _priv_hdrs)
list(APPEND CPACK_SOURCE_IGNORE_FILES ${_srcs} ${_pub_hdrs} ${_priv_hdrs})
endforeach()
list(APPEND CPACK_SOURCE_IGNORE_FILES "/.*build.*/;/CVS/;/\\\\.svn/;/\\\\.bzr/;/\\\\.hg/;/\\\\.hgignore;/\\\\.git/;\\\\.swp$;\\\\.#;/#;~")
include(CPack)
diff --git a/cmake/AkantuConfig.cmake.in b/cmake/AkantuConfig.cmake.in
index 455433c99..08c7aed2e 100644
--- a/cmake/AkantuConfig.cmake.in
+++ b/cmake/AkantuConfig.cmake.in
@@ -1,66 +1,68 @@
#===============================================================================
# @file AkantuConfig.cmake.in
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Thu Dec 01 18:00:05 2011
+# @date creation: Thu Dec 01 2011
+# @date last modification: Mon Nov 16 2015
#
# @brief CMake file for the library
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
# 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(AkantuExamplesMacros)
else()
# In install tree
set(AKANTU_INCLUDE_DIR "${AKANTU_CMAKE_DIR}/../../include/akantu")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${AKANTU_CMAKE_DIR}/cmake")
include(AkantuExamplesMacros)
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)
endif()
list(APPEND AKANTU_LIBRARIES ${AKANTU_LIBRARY} ${AKANTU_EXTRA_LIBRARIES})
list(APPEND AKANTU_INCLUDE_DIR ${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/AkantuConfigVersion.cmake.in b/cmake/AkantuConfigVersion.cmake.in
index 58272c1ab..db1b45bef 100644
--- a/cmake/AkantuConfigVersion.cmake.in
+++ b/cmake/AkantuConfigVersion.cmake.in
@@ -1,40 +1,42 @@
#===============================================================================
# @file AkantuConfigVersion.cmake.in
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Thu Dec 01 18:00:05 2011
+# @date creation: Thu Dec 01 2011
+# @date last modification: Sun Oct 19 2014
#
# @brief configures akantu version for cmake
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
set(PACKAGE_VERSION "@AKANTU_VERSION@")
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
diff --git a/cmake/AkantuExamplesMacros.cmake b/cmake/AkantuExamplesMacros.cmake
index 940a083ed..8bf79b561 100644
--- a/cmake/AkantuExamplesMacros.cmake
+++ b/cmake/AkantuExamplesMacros.cmake
@@ -1,175 +1,174 @@
#===============================================================================
-# @file AkantuTestAndExamples.cmake
+# @file AkantuExamplesMacros.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Oct 25 2010
-# @date last modification: Tue Jun 24 2014
+# @date creation: Mon Aug 17 2015
#
# @brief macros for examples
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
#===============================================================================
function(register_example example_name)
set(multi_variables
SOURCES
FILES_TO_COPY
DEPENDS
DIRECTORIES_TO_CREATE
COMPILE_OPTIONS
USE
)
cmake_parse_arguments(_opt_pkg
""
""
"${multi_variables}"
${ARGN}
)
set(_deps_OK TRUE)
if(_opt_pkg_USE)
foreach(_pkg ${_opt_pkg_USE})
package_is_activated(${_pkg} _activated)
if(_activated)
package_get_include_dir(${_pkg} _inc_dir)
list(APPEND _example_INCLUDE_DIRS ${_inc_dir})
package_get_libraries(${_pkg} _libraries)
list(APPEND _example_LIBRARIES ${_libraries})
package_get_compile_flags(${_pkg} _flags)
list(APPEND _example_COMPILE_FLAGS "${_flags}")
else()
message("${example_name} use ${_pkg} but Akantu "
" has been compiled without this package")
set(_deps_OK FALSE)
endif()
endforeach()
endif()
if(_deps_OK)
add_executable(${example_name}
${_opt_pkg_UNPARSED_ARGUMENTS} ${_opt_pkg_SOURCES})
target_link_libraries(${example_name}
akantu ${_example_LIBRARIES})
target_include_directories(${example_name}
PRIVATE ${_example_INCLUDE_DIRS})
if(_opt_pkg_DEPENDS)
foreach(_deps ${_opt_pkg_DEPENDS})
get_target_property(_type ${_deps} TYPE)
if(_type STREQUAL "SHARED_LIBRARY"
OR _type STREQUAL "STATIC_LIBRARY")
target_link_libraries(${example_name} ${_deps})
else()
add_dependencies(${example_name} ${_deps})
endif()
endforeach()
endif()
if(_opt_pkg_COMPILE_OPTIONS OR _example_COMPILE_FLAGS)
set_target_properties(${test_name}
PROPERTIES COMPILE_FLAGS "${_example_COMPILE_FLAGS} ${_opt_pkg_COMPILE_OPTIONS}")
endif()
# copy the needed files to the build folder
if(_opt_pkg_FILES_TO_COPY)
file(COPY ${_opt_pkg_FILES_TO_COPY} DESTINATION .)
endif()
# create the needed folders in the build folder
if(_opt_pkg_DIRECTORIES_TO_CREATE)
foreach(_dir ${_opt_pkg_DIRECTORIES_TO_CREATE})
if(IS_ABSOLUTE ${dir})
file(MAKE_DIRECTORY ${_dir})
else()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir})
endif()
endforeach()
endif()
endif()
endfunction()
#===============================================================================
function(add_example et_name desc)
string(TOUPPER ${et_name} upper_name)
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${et_name} AND _activated)
message(FATAL_ERROR "The folder ${CMAKE_CURRENT_SOURCE_DIR}/${et_name} "
"that you try to register as an example sub-folder, does not exists.")
endif()
cmake_parse_arguments(_manage_example
""
""
"PACKAGE"
${ARGN}
)
if(_manage_example_PACKAGE)
set(_act TRUE)
foreach(_pkg ${_manage_example_PACKAGE})
package_is_activated(${_pkg} _activated)
if(NOT _activated)
set(_act FALSE)
endif()
endforeach()
endif()
if(NOT (_act OR AKANTU_BUILD_ALL_EXAMPLES))
file(RELATIVE_PATH _dir ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${et_name})
list(APPEND AKANTU_TESTS_EXCLUDE_FILES /${_dir})
set(AKANTU_TESTS_EXCLUDE_FILES ${AKANTU_TESTS_EXCLUDE_FILES} CACHE INTERNAL "")
return()
endif()
option(AKANTU_BUILD_EXAMPLE_${upper_name} "${desc}")
mark_as_advanced(AKANTU_BUILD_${upper_name})
if(AKANTU_BUILD_ALL_EXAMPLES OR _act)
set(AKANTU_BUILD_EXAMPLE_${upper_name}_OLD
${AKANTU_BUILD_EXAMPLE_${upper_name}}
CACHE INTERNAL "${desc}" FORCE)
set(AKANTU_BUILD_EXAMPLE_${upper_name} ${_activated}
CACHE INTERNAL "${desc}" FORCE)
else()
if(DEFINED AKANTU_BUILD_EXAMPLE_${upper_name}_OLD)
set(AKANTU_BUILD_EXAMPLE_${upper_name}
${AKANTU_BUILD_EXAMPLE_${upper_name}_OLD}
CACHE BOOL "${desc}" FORCE)
unset(AKANTU_BUILD_EXAMPLE_${upper_name}_OLD
CACHE)
endif(DEFINED AKANTU_BUILD_EXAMPLE_${upper_name}_OLD)
endif()
if(AKANTU_BUILD_EXAMPLE_${upper_name})
add_subdirectory(${et_name})
endif(AKANTU_BUILD_EXAMPLE_${upper_name})
endfunction()
diff --git a/cmake/AkantuInstall.cmake b/cmake/AkantuInstall.cmake
index 50cb50c72..4b9423220 100644
--- a/cmake/AkantuInstall.cmake
+++ b/cmake/AkantuInstall.cmake
@@ -1,137 +1,138 @@
#===============================================================================
# @file AkantuInstall.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Wed Oct 17 2012
-# @date last modification: Fri Sep 19 2014
+# @date last modification: Wed Dec 02 2015
#
# @brief Create the files that allows users to link with Akantu in an other
# cmake project
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
#===============================================================================
# Config gen for external packages
#===============================================================================
configure_file(cmake/AkantuBuildTreeSettings.cmake.in "${PROJECT_BINARY_DIR}/AkantuBuildTreeSettings.cmake" @ONLY)
file(WRITE "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
#===============================================================================
# @file AkantuConfigInclude.cmake
# @author Nicolas Richart <nicolas.richart@epfl.ch>
# @date Fri Jun 11 09:46:59 2010
#
# @section LICENSE
#
# Copyright (©) 2010-2011 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
#
#===============================================================================
")
package_get_all_packages(_package_list)
foreach(_pkg_name ${_package_list})
# package_pkg_name(${_option} _pkg_name)
_package_is_activated(${_pkg_name} _acctivated)
_package_get_real_name(${_pkg_name} _real_name)
string(TOUPPER ${_real_name} _real_pkg_name)
file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
set(AKANTU_HAS_${_real_pkg_name} ${_acctivated})")
_package_get_libraries(${_pkg_name} _libs)
if(_libs)
file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
set(AKANTU_${_real_pkg_name}_LIBRARIES ${_libs})")
endif()
_package_get_include_dir(${_pkg_name} _incs)
if(_incs)
file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
set(AKANTU_${_real_pkg_name}_INCLUDE_DIR ${_incs})
")
endif()
_package_get_compile_flags(${_pkg_name} _compile_flags)
if(_compile_flags)
file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
set(AKANTU_${_real_pkg_name}_COMPILE_FLAGS ${_compile_flags})
")
endif()
endforeach()
file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
")
# Create the AkantuConfig.cmake and AkantuConfigVersion files
get_filename_component(CONF_REL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}" ABSOLUTE)
configure_file(cmake/AkantuConfig.cmake.in "${PROJECT_BINARY_DIR}/AkantuConfig.cmake" @ONLY)
configure_file(cmake/AkantuConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/AkantuConfigVersion.cmake" @ONLY)
configure_file(cmake/AkantuUse.cmake "${PROJECT_BINARY_DIR}/AkantuUse.cmake" COPYONLY)
# include(CMakePackageConfigHelpers)
# configure_package_config_file(cmake/AkantuConfig.cmake.in ${PROJECT_BINARY_DIR}/AkantuConfig.cmake
# INSTALL_DESTINATION "${CONF_REL_INCLUDE_DIR}lib/akantu/cmake"
# PATH_VARS "${CONF_REL_INCLUDE_DIR}/include" )
# write_basic_package_version_file(${PROJECT_BINARY_DIR}/AkantuConfigVersion.cmake
# VERSION "${AKANTU_VERSION}"
# COMPATIBILITY SameMajorVersion)
# Install the export set for use with the install-tree
install(FILES ${PROJECT_BINARY_DIR}/AkantuConfig.cmake
${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake
${PROJECT_BINARY_DIR}/AkantuConfigVersion.cmake
${PROJECT_SOURCE_DIR}/cmake/AkantuUse.cmake
DESTINATION lib/akantu
COMPONENT dev)
install(FILES
${PROJECT_SOURCE_DIR}/cmake/Modules/FindIOHelper.cmake
${PROJECT_SOURCE_DIR}/cmake/Modules/FindQVIEW.cmake
${PROJECT_SOURCE_DIR}/cmake/Modules/FindMumps.cmake
${PROJECT_SOURCE_DIR}/cmake/Modules/FindScotch.cmake
${PROJECT_SOURCE_DIR}/cmake/Modules/FindGMSH.cmake
DESTINATION lib/akantu/cmake
COMPONENT dev)
diff --git a/cmake/AkantuMacros.cmake b/cmake/AkantuMacros.cmake
index 822184445..688e76e23 100644
--- a/cmake/AkantuMacros.cmake
+++ b/cmake/AkantuMacros.cmake
@@ -1,345 +1,346 @@
#===============================================================================
# @file AkantuMacros.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Feb 17 2011
-# @date last modification: Tue Aug 19 2014
+# @date creation: Fri Oct 22 2010
+# @date last modification: Fri Dec 11 2015
#
# @brief Set of macros used by akantu cmake files
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
#===============================================================================
function(set_third_party_shared_libirary_name _var _lib)
set(${_var}
${PROJECT_BINARY_DIR}/third-party/lib/${CMAKE_SHARED_LIBRARY_PREFIX}${_lib}${CMAKE_SHARED_LIBRARY_SUFFIX}
CACHE FILEPATH "" FORCE)
endfunction()
#===============================================================================
# Generate the list of currently loaded materials
function(generate_material_list)
message(STATUS "Determining the list of recognized materials...")
package_get_all_include_directories(
AKANTU_LIBRARY_INCLUDE_DIRS
)
package_get_all_external_informations(
AKANTU_EXTERNAL_INCLUDE_DIR
AKANTU_EXTERNAL_LIBRARIES
)
set(_include_dirs ${AKANTU_INCLUDE_DIRS} ${AKANTU_EXTERNAL_INCLUDE_DIR})
try_run(_material_list_run _material_list_compile
${CMAKE_BINARY_DIR}
${PROJECT_SOURCE_DIR}/cmake/material_lister.cc
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${_include_dirs}"
COMPILE_DEFINITIONS "-DAKANTU_CMAKE_LIST_MATERIALS"
COMPILE_OUTPUT_VARIABLE _compile_results
RUN_OUTPUT_VARIABLE _result_material_list)
if(_material_list_compile AND "${_material_list_run}" EQUAL 0)
message(STATUS "Materials included in Akantu:")
string(REPLACE "\n" ";" _material_list "${_result_material_list}")
foreach(_mat ${_material_list})
string(REPLACE ":" ";" _mat_key "${_mat}")
list(GET _mat_key 0 _key)
list(GET _mat_key 1 _class)
list(LENGTH _mat_key _l)
if("${_l}" GREATER 2)
list(REMOVE_AT _mat_key 0 1)
set(_opt " -- options: [")
foreach(_o ${_mat_key})
set(_opt "${_opt} ${_o}")
endforeach()
set(_opt "${_opt} ]")
else()
set(_opt "")
endif()
message(STATUS " ${_class} -- key: ${_key}${_opt}")
endforeach()
else()
message(STATUS "Could not determine the list of materials.")
message("${_compile_results}")
endif()
endfunction()
#===============================================================================
# Declare the options for the types and defines the approriate typedefs
function(declare_akantu_types)
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag (-std=c++0x HAVE_CPP_0X)
unset(_cpp_11_flag)
if(HAVE_CPP_0X)
set(_cpp_11_flag "-std=c++0x")
else()
check_cxx_compiler_flag (-std=c++11 HAVE_CPP_11)
if(HAVE_CPP_11)
set(_cpp_11_flag "-std=c++11")
endif()
endif()
set(AKANTU_CXX11_FLAGS "${_cpp_11_flag}" CACHE INTERNAL "")
set(AKANTU_TYPE_FLOAT "double (64bit)" CACHE STRING "Precision force floating point types")
mark_as_advanced(AKANTU_TYPE_FLOAT)
set_property(CACHE AKANTU_TYPE_FLOAT PROPERTY STRINGS
"quadruple (128bit)"
"double (64bit)"
"float (32bit)"
)
set(AKANTU_TYPE_INTEGER "int (32bit)" CACHE STRING "Size of the integer types")
mark_as_advanced(AKANTU_TYPE_INTEGER)
set_property(CACHE AKANTU_TYPE_INTEGER PROPERTY STRINGS
"int (32bit)"
"long int (64bit)"
)
include(CheckTypeSize)
# ----------------------------------------------------------------------------
# Floating point types
# ----------------------------------------------------------------------------
if(AKANTU_TYPE_FLOAT STREQUAL "float (32bit)")
set(AKANTU_FLOAT_TYPE "float" CACHE INTERNAL "")
set(AKANTU_FLOAT_SIZE 4 CACHE INTERNAL "")
elseif(AKANTU_TYPE_FLOAT STREQUAL "double (64bit)")
set(AKANTU_FLOAT_TYPE "double" CACHE INTERNAL "")
set(AKANTU_FLOAT_SIZE 8 CACHE INTERNAL "")
elseif(AKANTU_TYPE_FLOAT STREQUAL "quadruple (128bit)")
check_type_size("long double" LONG_DOUBLE)
if(HAVE_LONG_DOUBLE)
set(AKANTU_FLOAT_TYPE "long double" CACHE INTERNAL "")
set(AKANTU_FLOAT_SIZE 16 CACHE INTERNAL "")
message("This feature is not tested and will most probably not compile")
else()
message(FATAL_ERROR "The type long double is not defined on your system")
endif()
else()
message(FATAL_ERROR "The float type is not defined")
endif()
include(CheckIncludeFileCXX)
include(CheckCXXSourceCompiles)
# ----------------------------------------------------------------------------
# Integer types
# ----------------------------------------------------------------------------
check_include_file_cxx(cstdint HAVE_CSTDINT)
if(NOT HAVE_CSTDINT)
check_include_file_cxx(stdint.h HAVE_STDINT_H)
if(HAVE_STDINT_H)
list(APPEND _int_include stdint.h)
endif()
else()
list(APPEND _int_include cstdint)
endif()
check_include_file_cxx(cstddef HAVE_CSTDDEF)
if(NOT HAVE_CSTDINT)
check_include_file_cxx(stddef.h HAVE_STDDEF_H)
if(HAVE_STDINT_H)
list(APPEND _int_include stddef.h)
endif()
else()
list(APPEND _int_include cstddef)
endif()
if(AKANTU_TYPE_INTEGER STREQUAL "int (32bit)")
set(AKANTU_INTEGER_SIZE 4 CACHE INTERNAL "")
check_type_size("int" INT)
if(INT EQUAL 4)
set(AKANTU_SIGNED_INTEGER_TYPE "int" CACHE INTERNAL "")
set(AKANTU_UNSIGNED_INTEGER_TYPE "unsigned int" CACHE INTERNAL "")
else()
check_type_size("int32_t" INT32_T LANGUAGE CXX)
if(HAVE_INT32_T)
set(AKANTU_SIGNED_INTEGER_TYPE "int32_t" CACHE INTERNAL "")
set(AKANTU_UNSIGNED_INTEGER_TYPE "uint32_t" CACHE INTERNAL "")
list(APPEND _extra_includes ${_int_include})
endif()
endif()
elseif(AKANTU_TYPE_INTEGER STREQUAL "long int (64bit)")
set(AKANTU_INTEGER_SIZE 8 CACHE INTERNAL "")
check_type_size("long int" LONG_INT)
if(LONG_INT EQUAL 8)
set(AKANTU_SIGNED_INTEGER_TYPE "long int" CACHE INTERNAL "")
set(AKANTU_UNSIGNED_INTEGER_TYPE "unsigned long int" CACHE INTERNAL "")
else()
check_type_size("long long int" LONG_LONG_INT)
if(HAVE_LONG_LONG_INT AND LONG_LONG_INT EQUAL 8)
set(AKANTU_SIGNED_INTEGER_TYPE "long long int" CACHE INTERNAL "")
set(AKANTU_UNSIGNED_INTEGER_TYPE "unsigned long long int" CACHE INTERNAL "")
else()
check_type_size("int64_t" INT64_T)
if(HAVE_INT64_T)
set(AKANTU_SIGNED_INTEGER_TYPE "int64_t" CACHE INTERNAL "")
set(AKANTU_UNSIGNED_INTEGER_TYPE "uint64_t" CACHE INTERNAL "")
list(APPEND _extra_includes ${_int_include})
endif()
endif()
endif()
else()
message(FATAL_ERROR "The integer type is not defined")
endif()
# ----------------------------------------------------------------------------
# unordered map type
# ----------------------------------------------------------------------------
check_include_file_cxx(unordered_map HAVE_UNORDERED_MAP)
set(AKANTU_UNORDERED_MAP_IS_CXX11 TRUE CACHE INTERNAL "")
if(HAVE_UNORDERED_MAP)
list(APPEND _extra_includes unordered_map)
set(AKANTU_UNORDERED_MAP_TYPE "std::unordered_map" CACHE INTERNAL "")
set(AKANTU_UNORDERED_MAP_NAMESPACE_BEGIN "namespace std {" CACHE INTERNAL "")
set(AKANTU_UNORDERED_MAP_NAMESPACE_END "}" CACHE INTERNAL "")
else()
check_include_file_cxx(tr1/unordered_map HAVE_TR1_UNORDERED_MAP)
if(HAVE_TR1_UNORDERED_MAP)
list(APPEND _extra_includes tr1/unordered_map)
set(AKANTU_UNORDERED_MAP_TYPE "std::tr1::unordered_map" CACHE INTERNAL "")
set(AKANTU_UNORDERED_MAP_NAMESPACE_BEGIN "namespace std { namespace tr1 {" CACHE INTERNAL "")
set(AKANTU_UNORDERED_MAP_NAMESPACE_END "}}" CACHE INTERNAL "")
else()
list(APPEND _extra_includes map)
set(AKANTU_UNORDERED_MAP_TYPE "std::map" CACHE INTERNAL "")
set(AKANTU_UNORDERED_MAP_IS_CXX11 FALSE CACHE INTERNAL "")
endif()
endif()
# ----------------------------------------------------------------------------
# hash function
# ----------------------------------------------------------------------------
unset(AKANTU_HASH_TYPE CACHE)
check_include_file_cxx(functional HAVE_FUNCTIONAL)
set(AKANTU_HASH_IS_CXX11 TRUE CACHE INTERNAL "")
if(HAVE_FUNCTIONAL AND AKANTU_CXX11_FLAGS)
list(APPEND _extra_includes functional)
check_cxx_source_compiles("
#include <functional>
template<class T>
std::size_t hash(const T & t) {
typedef typename std::hash<T> hash_type;
return hash_type()(t);
};
int main() { return 0; }
" HAVE_HASH)
if(HAVE_HASH)
set(AKANTU_HASH_TYPE "std::hash" CACHE INTERNAL "")
endif()
endif()
if(NOT AKANTU_HASH_TYPE)
check_include_file_cxx(tr1/functional HAVE_TR1_HASH)
if(HAVE_TR1_HASH)
list(APPEND _extra_includes tr1/functional)
set(AKANTU_HASH_TYPE "std::tr1::hash" CACHE INTERNAL "")
else()
check_include_file_cxx(boost/functional/hash.hpp HAVE_BOOST_HASH)
list(APPEND _extra_includes boost/functional/hash.hpp)
set(AKANTU_HASH_TYPE "boost::hash" CACHE INTERNAL "")
set(AKANTU_HASH_IS_CXX11 FALSE CACHE INTERNAL "")
endif()
endif()
# ----------------------------------------------------------------------------
# includes
# ----------------------------------------------------------------------------
foreach(_inc ${_extra_includes})
set(_incs "#include <${_inc}>\n${_incs}")
endforeach()
set(AKANTU_TYPES_EXTRA_INCLUDES ${_incs} CACHE INTERNAL "")
endfunction()
#===============================================================================
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
return()
endif()
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
# first set all result variables to empty/FALSE
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
set(${prefix}_${arg_name})
endforeach(arg_name)
foreach(option ${_optionNames})
set(${prefix}_${option} FALSE)
endforeach(option)
set(${prefix}_UNPARSED_ARGUMENTS)
set(insideValues FALSE)
set(currentArgName)
# now iterate over all arguments and fill the result variables
foreach(currentArg ${ARGN})
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
if(insideValues)
if("${insideValues}" STREQUAL "SINGLE")
set(${prefix}_${currentArgName} ${currentArg})
set(insideValues FALSE)
elseif("${insideValues}" STREQUAL "MULTI")
list(APPEND ${prefix}_${currentArgName} ${currentArg})
endif()
else(insideValues)
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
endif(insideValues)
else()
if(NOT ${optionIndex} EQUAL -1)
set(${prefix}_${currentArg} TRUE)
set(insideValues FALSE)
elseif(NOT ${singleArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "SINGLE")
elseif(NOT ${multiArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "MULTI")
endif()
endif()
endforeach(currentArg)
# propagate the result variables to the caller:
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
endforeach(arg_name)
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)
diff --git a/cmake/AkantuPackagesSystem.cmake b/cmake/AkantuPackagesSystem.cmake
index 40ad2d43b..5a178e880 100644
--- a/cmake/AkantuPackagesSystem.cmake
+++ b/cmake/AkantuPackagesSystem.cmake
@@ -1,283 +1,286 @@
#===============================================================================
-# @file CMakePackagesSystem.cmake
+# @file AkantuPackagesSystem.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Sat Jul 18 2015
+# @date last modification: Mon Nov 16 2015
+#
# @brief Addition to the PackageSystem specific for Akantu
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
#===============================================================================
# Element Types
#===============================================================================
#-------------------------------------------------------------------------------
function(package_declare_elements pkg)
set(_options
KIND
ELEMENT_TYPES
GEOMETRICAL_TYPES
INTERPOLATION_TYPES
GEOMETRICAL_SHAPES
GAUSS_INTEGRATION_TYPES
INTERPOLATION_TYPES
INTERPOLATION_KIND
FE_ENGINE_LISTS
)
cmake_parse_arguments(_opt_pkg
""
""
"${_options}"
${ARGN})
foreach(_opt ${_options})
if(_opt_pkg_${_opt})
package_set_variable(ET_${_opt} ${pkg} ${_opt_pkg_${_opt}})
endif()
endforeach()
endfunction()
#-------------------------------------------------------------------------------
function(_transfer_list_to_enum types enum)
if(${enum})
set(_enum_tmp ${${enum}})
else()
unset(_enum_tmp)
endif()
foreach(_type ${${types}})
# defining the types for the enum
if(DEFINED _enum_tmp)
set(_enum_tmp "${_enum_tmp}
${_type},")
else()
set(_enum_tmp "${_type},")
endif()
endforeach()
set(${enum} ${_enum_tmp} PARENT_SCOPE)
endfunction()
#-------------------------------------------------------------------------------
function(_transfer_list_to_boost_seq types boost_seq)
if(${boost_seq})
set(_boost_seq_tmp ${${boost_seq}})
endif()
foreach(_type ${${types}})
if(DEFINED _boost_seq_tmp)
set(_boost_seq_tmp "${_boost_seq_tmp}${_tabs}\\
(${_type})")
else()
set(_boost_seq_tmp " (${_type})")
endif()
string(LENGTH "${_type}" _length)
if(_length LESS 13)
set(_tabs "\t\t\t\t")
elseif(_length LESS 28)
set(_tabs "\t\t\t")
else()
set(_tabs "\t\t")
endif()
endforeach()
set(${boost_seq} ${_boost_seq_tmp} PARENT_SCOPE)
endfunction()
#-------------------------------------------------------------------------------
function(package_get_element_lists)
package_get_all_activated_packages(_activated_list)
set(_lists
KIND
ELEMENT_TYPES
GEOMETRICAL_TYPES
INTERPOLATION_TYPES
GEOMETRICAL_SHAPES
GAUSS_INTEGRATION_TYPES
INTERPOLATION_TYPES
INTERPOLATION_KIND
FE_ENGINE_LISTS
)
set(_element_kind "#define AKANTU_ELEMENT_KIND")
set(_all_element_types "#define AKANTU_ALL_ELEMENT_TYPE\t")
set(_inter_types_boost_seq "#define AKANTU_INTERPOLATION_TYPES\t\t")
foreach(_pkg_name ${_activated_list})
foreach(_list ${_lists})
string(TOLOWER "${_list}" _l_list)
_package_get_variable(ET_${_list} ${_pkg_name} _${_l_list})
_transfer_list_to_enum(_${_l_list} _${_l_list}_enum)
endforeach()
if(_interpolation_types)
_transfer_list_to_boost_seq(_interpolation_types _inter_types_boost_seq)
endif()
if(_kind)
string(TOUPPER "${_kind}" _u_kind)
if(_element_types)
set(_boosted_element_types "${_boosted_element_types}
#define AKANTU_ek_${_kind}_ELEMENT_TYPE\t")
_transfer_list_to_boost_seq(_element_types _boosted_element_types)
set(_boosted_element_types "${_boosted_element_types}\n")
# defininf the kinds variables
set(_element_kinds "${_element_kinds}
#define AKANTU_${_u_kind}_KIND\t(_ek_${_kind})")
# defining the full list of element
set(_all_element_types "${_all_element_types}\t\\
AKANTU_ek_${_kind}_ELEMENT_TYPE")
endif()
# defining the full list of kinds
set(_element_kind "${_element_kind}${_kind_tabs}\t\t\\
AKANTU_${_u_kind}_KIND")
set(_kind_tabs "\t")
# defining the macros
set(_boost_macros "${_boost_macros}
#define AKANTU_BOOST_${_u_kind}_ELEMENT_SWITCH(macro) \\
AKANTU_BOOST_ELEMENT_SWITCH(macro, \\
AKANTU_ek_${_kind}_ELEMENT_TYPE)
#define AKANTU_BOOST_${_u_kind}_ELEMENT_LIST(macro) \\
AKANTU_BOOST_APPLY_ON_LIST(macro, \\
AKANTU_ek_${_kind}_ELEMENT_TYPE)
")
list(APPEND _aka_fe_lists ${_fe_engine_lists})
foreach(_fe_engine_list ${_fe_engine_lists})
if(NOT DEFINED _fe_engine_list_${_fe_engine_list})
string(TOUPPER "${_fe_engine_list}" _u_list)
string(LENGTH "#define AKANTU_FE_ENGINE_LIST_${_u_list}" _length)
math(EXPR _length "72 - ${_length}")
set(_space "")
while(_length GREATER 0)
if(CMAKE_VERSION VERSION_GREATER 3.0)
string(CONCAT _space "${_space}" " ")
else()
set(_space "${_space} ")
endif()
math(EXPR _length "${_length} - 1")
endwhile()
set(_fe_engine_list_${_fe_engine_list}
"#define AKANTU_FE_ENGINE_LIST_${_u_list}${_space}\\
AKANTU_GENERATE_KIND_LIST((_ek_${_kind})")
else()
set(_fe_engine_list_${_fe_engine_list}
"${_fe_engine_list_${_fe_engine_list}}\t\t\t\t\\
(_ek_${_kind})")
endif()
endforeach()
endif()
endforeach()
if(_aka_fe_lists)
list(REMOVE_DUPLICATES _aka_fe_lists)
foreach(_fe_list ${_aka_fe_lists})
set(_aka_fe_defines "${_fe_engine_list_${_fe_list}})\n${_aka_fe_defines}")
endforeach()
endif()
# package_get_all_deactivated_packages(_deactivated_list)
# foreach(_pkg_name ${_deactivated_list})
# _package_get_variable(ET_KIND ${_pkg_name} _kind)
# if(_kind)
# string(TOUPPER "${_kind}" _u_kind)
# set(_element_kinds "${_element_kinds}
# #define AKANTU_${_u_kind}_KIND")
# endif()
# endforeach()
foreach(_list ${_lists})
string(TOLOWER "${_list}" _l_list)
set(AKANTU_${_list}_ENUM ${_${_l_list}_enum} PARENT_SCOPE)
endforeach()
set(AKANTU_INTERPOLATION_TYPES_BOOST_SEQ ${_inter_types_boost_seq} PARENT_SCOPE)
set(AKANTU_ELEMENT_TYPES_BOOST_SEQ ${_boosted_element_types} PARENT_SCOPE)
set(AKANTU_ELEMENT_KINDS_BOOST_SEQ ${_element_kinds} PARENT_SCOPE)
set(AKANTU_ELEMENT_KIND_BOOST_SEQ ${_element_kind} PARENT_SCOPE)
set(AKANTU_ALL_ELEMENT_BOOST_SEQ ${_all_element_types} PARENT_SCOPE)
set(AKANTU_ELEMENT_KINDS_BOOST_MACROS ${_boost_macros} PARENT_SCOPE)
set(AKANTU_FE_ENGINE_LISTS ${_aka_fe_defines} PARENT_SCOPE)
endfunction()
#-------------------------------------------------------------------------------
function(package_get_element_types pkg list)
package_get_name(${pkg} _pkg_name)
_package_get_variable(ET_ELEMENT_TYPES ${_pkg_name} _tmp_list)
set(${list} ${_tmp_list} PARENT_SCOPE)
endfunction()
#===============================================================================
# Material specific
#===============================================================================
#-------------------------------------------------------------------------------
function(package_declare_material_infos pkg)
cmake_parse_arguments(_opt_pkg
""
""
"LIST;INCLUDE"
${ARGN})
package_set_variable(MATERIAL_LIST ${pkg} ${_opt_pkg_LIST})
package_set_variable(MATERIAL_INCLUDE ${pkg} ${_opt_pkg_INCLUDE})
endfunction()
#-------------------------------------------------------------------------------
function(package_get_all_material_includes includes)
_package_get_variable_for_activated(MATERIAL_INCLUDE _includes)
foreach(_mat_inc ${_includes})
if(DEFINED _mat_includes)
set(_mat_includes "${_mat_includes}\n#include \"${_mat_inc}\"")
else()
set(_mat_includes "#include \"${_mat_inc}\"")
endif()
endforeach()
set(${includes} ${_mat_includes} PARENT_SCOPE)
endfunction()
#-------------------------------------------------------------------------------
function(package_get_all_material_lists lists)
_package_get_variable_for_activated(MATERIAL_LIST _lists)
foreach(_mat_list ${_lists})
if(DEFINED _mat_lists)
set(_mat_lists "${_mat_lists}\n ${_mat_list}\t\t\t\\")
else()
set(_mat_lists " ${_mat_list}\t\t\t\\")
endif()
endforeach()
set(${lists} ${_mat_lists} PARENT_SCOPE)
endfunction()
#-------------------------------------------------------------------------------
diff --git a/cmake/AkantuTestsMacros.cmake b/cmake/AkantuTestsMacros.cmake
index 7f3edb406..3591c1ed9 100644
--- a/cmake/AkantuTestsMacros.cmake
+++ b/cmake/AkantuTestsMacros.cmake
@@ -1,381 +1,383 @@
#===============================================================================
-# @file AkantuTestMacros.cmake
+# @file AkantuTestsMacros.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Oct 25 2010
-# @date last modification: Tue Jun 24 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Fri Jan 15 2016
#
# @brief macros for tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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>...]
# [UNSABLE]
# [PARALLEL]
# )
#
# 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``
#
#]=======================================================================]
set(AKANTU_DRIVER_SCRIPT ${AKANTU_CMAKE_DIR}/akantu_test_driver.sh)
configure_file(${AKANTU_CMAKE_DIR}/akantu_test_environement.sh.in
${PROJECT_BINARY_DIR}/akantu_test_environement.sh
@ONLY)
# ==============================================================================
macro(add_test_tree dir)
if(AKANTU_TESTS)
enable_testing()
include(CTest)
mark_as_advanced(BUILD_TESTING)
set(AKANTU_TESTS_EXCLUDE_FILES "" CACHE INTERNAL "")
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()
else()
set(AKANTU_TESTS_EXCLUDE_FILES "${CMAKE_CURRENT_BINARY_DIR}/${dir}" CACHE INTERNAL "")
endif()
endmacro()
# ==============================================================================
function(add_akantu_test dir desc)
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(register_test test_name)
set(multi_variables
SOURCES FILES_TO_COPY DEPENDS DIRECTORIES_TO_CREATE COMPILE_OPTIONS EXTRA_FILES PACKAGE
)
cmake_parse_arguments(_register_test
"UNSTABLE;PARALLEL"
"POSTPROCESS;SCRIPT"
"${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()
# 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()
foreach(_file ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS})
if(NOT (_file MATCHES "\\.cc$" OR _file MATCHES "\\.hh$"))
set(_need_to_compile FALSE)
message("NO: ${test_name}")
endif()
endforeach()
# todo this should be checked for the build package_sources since the file will not be listed.
if(_test_act)
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)
string(TOUPPER ${_akantu_current_parent_test} _u_parent)
if(AKANTU_BUILD_${_u_parent} OR AKANTU_BUILD_ALL_TESTS)
set(_test_all_files)
if(_need_to_compile)
# 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(
AKANTU_EXTERNAL_INCLUDE_DIR
AKANTU_EXTERNAL_LIBRARIES
)
# set the proper includes to build most of the tests
include_directories(
${AKANTU_INCLUDE_DIRS}
${AKANTU_EXTERNAL_LIB_INCLUDE_DIR}
)
# Register the executable to compile
add_executable(${test_name} ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS})
set_property(TARGET ${test_name} APPEND
PROPERTY INCLUDE_DIRECTORIES ${AKANTU_LIBRARY_INCLUDE_DIRS} ${AKANTU_EXTERNAL_INCLUDE_DIR})
target_link_libraries(${test_name} akantu ${AKANTU_EXTERNAL_LIBRARIES})
# add the extra compilation options
if(_register_test_COMPILE_OPTIONS)
set_target_properties(${test_name}
PROPERTIES COMPILE_DEFINITIONS "${_register_test_COMPILE_OPTIONS}")
endif()
# add the different dependencies (meshes, local libraries, ...)
foreach(_dep ${_register_test_DEPENDS})
add_dependencies(${test_name} ${_dep})
get_target_property(_dep_in_ressources ${_dep} RESSOURCES)
if(_dep_in_ressources)
list(APPEND _test_all_files "${_dep_in_ressources}")
endif()
endforeach()
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 .)
list(APPEND _test_all_files "${CMAKE_CURRENT_SOURCE_DIR}/${_file}")
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()
# add the source files in the list of all files
foreach(_file ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS} ${_register_test_EXTRA_FILES})
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
list(APPEND _test_all_files "${CMAKE_CURRENT_SOURCE_DIR}/${_file}")
else()
message("The file \"${_file}\" registred by the test \"${test_name}\" does not exists")
endif()
endforeach()
set(_arguments -n "${test_name}")
# register the test for ctest
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 _test_all_files "${CMAKE_CURRENT_SOURCE_DIR}/${_register_test_SCRIPT}")
list(APPEND _arguments -e "${_register_test_SCRIPT}")
elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh")
file(COPY ${test_name}.sh DESTINATION .)
list(APPEND _test_all_files "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh")
list(APPEND _arguments -e "${test_name}.sh")
else()
list(APPEND _arguments -e "${test_name}")
endif()
list(APPEND _arguments -E "${PROJECT_BINARY_DIR}/akantu_test_environement.sh")
if(_register_test_PARALLEL)
list(APPEND _arguments -p "${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG}")
endif()
if(_register_test_POSTPROCESS)
list(APPEND _arguments -s "${_register_test_POSTPROCESS}")
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}")
add_test(NAME ${test_name}_run
COMMAND ${AKANTU_DRIVER_SCRIPT} ${_arguments})
# add the executable as a dependency of the run
set_tests_properties(${test_name}_run PROPERTIES DEPENDS ${test_name})
# clean the list of all files for this test and add them in the total list
set(_tmp ${AKANTU_TESTS_FILES})
foreach(_file ${_source_file})
get_filename_component(_full ${_file} ABSOLUTE)
file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_full})
list(APPEND _tmp "${__file}")
list(APPEND _pkg_tmp "${__file}")
endforeach()
set(AKANTU_TESTS_FILES ${_tmp} CACHE INTERNAL "")
endif()
endif()
endfunction()
diff --git a/cmake/AkantuUse.cmake b/cmake/AkantuUse.cmake
index 00add8aa1..8847a75db 100644
--- a/cmake/AkantuUse.cmake
+++ b/cmake/AkantuUse.cmake
@@ -1,49 +1,50 @@
#===============================================================================
# @file AkantuUse.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Dec 01 2011
-# @date last modification: Tue Nov 06 2012
+# @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 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
function(package_is_activated pgk activated)
string(TOUPPER ${pkg} _u_pkg)
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)
endfunction()
function(package_get_libraries pkg libs)
string(TOUPPER ${pkg} _u_pkg)
set(libs ${AKANTU_${_u_pkg}_LIBRARIES} PARENT_SCOPE)
endfunction()
function(package_get_compile_flags pkg flags)
string(TOUPPER ${pkg} _u_pkg)
set(flags ${AKANTU_${_u_pkg}_COMPILE_FLAGS} PARENT_SCOPE)
endfunction()
diff --git a/cmake/Modules/CMakeDebugMessages.cmake b/cmake/Modules/CMakeDebugMessages.cmake
index b53c13d59..0a2ae2dff 100644
--- a/cmake/Modules/CMakeDebugMessages.cmake
+++ b/cmake/Modules/CMakeDebugMessages.cmake
@@ -1,71 +1,70 @@
#===============================================================================
# @file CMakeDebugMessages.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Dec 20 2012
-# @date last modification: Fri Jan 04 2013
+# @date creation: Sun Oct 19 2014
#
# @brief Debug message helper
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
if(__CMAKE_DEBUG_MESSAGES)
return()
endif()
set(__CMAKE_DEBUG_MESSAGES TRUE)
macro(cmake_register_debug_message_module module)
set(_CMAKE_DEBUG_MESSAGE_MODULES ${CMAKE_DEBUG_MESSAGE_MODULES})
list(APPEND _CMAKE_DEBUG_MESSAGE_MODULES ${module})
set(CMAKE_DEBUG_MESSAGE_MODULES "${_CMAKE_DEBUG_MESSAGE_MODULES}"
CACHE INTERNAL "List of modules handled by the debug messages system" FORCE)
endmacro()
macro(cmake_activate_debug_message)
set(_default FALSE)
if(ARGC EQUAL 0)
set(_default TRUE)
endif()
foreach(_module ${CMAKE_DEBUG_MESSAGE_MODULES})
set(CMAKE_DEBUG_MESSAGE_${_module} ${_default} CACHE INTERNAL "" FORCE)
endforeach()
foreach(_module ${ARGN})
set(CMAKE_DEBUG_MESSAGE_${_module} TRUE CACHE INTERNAL "" FORCE)
endforeach()
endmacro()
macro(cmake_deactivate_debug_message)
foreach(_module ${CMAKE_DEBUG_MESSAGE_MODULES})
if(CMAKE_DEBUG_MESSAGE_${_module})
set(CMAKE_DEBUG_MESSAGE_${_module} FALSE CACHE INTERNAL "" FORCE)
endif()
endforeach()
endmacro()
macro(cmake_debug_message module)
if(CMAKE_DEBUG_MESSAGE_${module})
message("${PROJECT_NAME} - ${module}: ${ARGN}")
endif()
endmacro()
\ No newline at end of file
diff --git a/cmake/Modules/CMakeDetermineCCompiler.cmake b/cmake/Modules/CMakeDetermineCCompiler.cmake
index 1c4fbc864..1def08a1e 100644
--- a/cmake/Modules/CMakeDetermineCCompiler.cmake
+++ b/cmake/Modules/CMakeDetermineCCompiler.cmake
@@ -1,66 +1,66 @@
#===============================================================================
-# @file AkantuDetermineCCompiler.cmake
+# @file CMakeDetermineCCompiler.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Thu Aug 02 10:34:06 2012
+# @date creation: Sun Oct 19 2014
#
# @brief CMake file to determine the compiler
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
macro(determine_compiler_version COMPILER)
exec_program(${CMAKE_CXX_COMPILER}
ARGS --version
OUTPUT_VARIABLE _temp
)
set(${COMPILER}_COMPILER_VERSION "" CACHE STRING "Vesion of ${COMPILER} compiler.")
string(REGEX MATCH "([0-9\\.]+)"
${COMPILER}_COMPILER_VERSION
${_temp}
)
mark_as_advanced(${COMPILER}_COMPILER_VERSION)
endmacro()
# Code from James Bigler (http://www.cmake.org/pipermail/cmake/2007-June/014460.html)
set(MANTA_COMPILER_NAME_REGEXPR "icc.*$")
if(NOT CMAKE_COMPILER_IS_GNUCC)
# This regular expression also matches things like icc-9.1
if(CMAKE_C_COMPILER MATCHES ${MANTA_COMPILER_NAME_REGEXPR})
set(AKANTU_USING_ICC TRUE)
endif(CMAKE_C_COMPILER MATCHES ${MANTA_COMPILER_NAME_REGEXPR})
else(NOT CMAKE_COMPILER_IS_GNUCC)
set(AKANTU_USING_GNUCC TRUE)
endif(NOT CMAKE_COMPILER_IS_GNUCC)
set(MANTA_COMPILER_NAME_REGEXPR "icpc.*$")
if(NOT CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_CXX_COMPILER MATCHES ${MANTA_COMPILER_NAME_REGEXPR})
set(AKANTU_USING_ICPC TRUE)
determine_compiler_version(INTEL)
#else mvsc/clang/ibm/... ?
endif(CMAKE_CXX_COMPILER MATCHES ${MANTA_COMPILER_NAME_REGEXPR})
else(NOT CMAKE_COMPILER_IS_GNUCXX)
set(AKANTU_USING_GNUCXX TRUE)
determine_compiler_version(GCC)
endif(NOT CMAKE_COMPILER_IS_GNUCXX)
diff --git a/cmake/Modules/CMakeDetermineCompiler.cmake b/cmake/Modules/CMakeDetermineCompiler.cmake
index 8bbdbc04c..97c9969d8 100644
--- a/cmake/Modules/CMakeDetermineCompiler.cmake
+++ b/cmake/Modules/CMakeDetermineCompiler.cmake
@@ -1,87 +1,102 @@
-# not present in CMake <=2.8.7 so local copy to correct the problem for cpp-array
-
-
-#=============================================================================
-# Copyright 2004-2012 Kitware, Inc.
+#===============================================================================
+# @file CMakeDetermineCompiler.cmake
+#
+#
+# @date creation: Sun Oct 19 2014
+#
+# @brief
#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
+# @section LICENSE
#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
+# 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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
macro(_cmake_find_compiler lang)
# Use already-enabled languages for reference.
get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
list(REMOVE_ITEM _languages "${lang}")
if(CMAKE_${lang}_COMPILER_INIT)
# Search only for the specified compiler.
set(CMAKE_${lang}_COMPILER_LIST "${CMAKE_${lang}_COMPILER_INIT}")
else()
# Re-order the compiler list with preferred vendors first.
set(_${lang}_COMPILER_LIST "${CMAKE_${lang}_COMPILER_LIST}")
set(CMAKE_${lang}_COMPILER_LIST "")
# Prefer vendors of compilers from reference languages.
foreach(l ${_languages})
list(APPEND CMAKE_${lang}_COMPILER_LIST
${_${lang}_COMPILER_NAMES_${CMAKE_${l}_COMPILER_ID}})
endforeach()
# Prefer vendors based on the platform.
list(APPEND CMAKE_${lang}_COMPILER_LIST ${CMAKE_${lang}_COMPILER_NAMES})
# Append the rest of the list and remove duplicates.
list(APPEND CMAKE_${lang}_COMPILER_LIST ${_${lang}_COMPILER_LIST})
unset(_${lang}_COMPILER_LIST)
list(REMOVE_DUPLICATES CMAKE_${lang}_COMPILER_LIST)
if(CMAKE_${lang}_COMPILER_EXCLUDE)
list(REMOVE_ITEM CMAKE_${lang}_COMPILER_LIST
${CMAKE_${lang}_COMPILER_EXCLUDE})
endif()
endif()
# Look for directories containing compilers of reference languages.
set(_${lang}_COMPILER_HINTS)
foreach(l ${_languages})
if(CMAKE_${l}_COMPILER AND IS_ABSOLUTE "${CMAKE_${l}_COMPILER}")
get_filename_component(_hint "${CMAKE_${l}_COMPILER}" PATH)
if(IS_DIRECTORY "${_hint}")
list(APPEND _${lang}_COMPILER_HINTS "${_hint}")
endif()
unset(_hint)
endif()
endforeach()
# Find the compiler.
if(_${lang}_COMPILER_HINTS)
# Prefer directories containing compilers of reference languages.
list(REMOVE_DUPLICATES _${lang}_COMPILER_HINTS)
find_program(CMAKE_${lang}_COMPILER
NAMES ${CMAKE_${lang}_COMPILER_LIST}
PATHS ${_${lang}_COMPILER_HINTS}
NO_DEFAULT_PATH
DOC "${lang} compiler")
endif()
find_program(CMAKE_${lang}_COMPILER NAMES ${CMAKE_${lang}_COMPILER_LIST} DOC "${lang} compiler")
if(CMAKE_${lang}_COMPILER_INIT AND NOT CMAKE_${lang}_COMPILER)
set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_INIT}" CACHE FILEPATH "${lang} compiler" FORCE)
endif()
unset(_${lang}_COMPILER_HINTS)
unset(_languages)
# Look for a make tool provided by Xcode
if(CMAKE_${lang}_COMPILER STREQUAL "CMAKE_${lang}_COMPILER-NOTFOUND" AND CMAKE_HOST_APPLE)
foreach(comp ${CMAKE_${lang}_COMPILER_LIST})
execute_process(COMMAND xcrun --find ${comp}
OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE _xcrun_err)
if(_xcrun_out)
set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${_xcrun_out}")
break()
endif()
endforeach()
endif()
endmacro()
diff --git a/cmake/Modules/CMakeFlagsHandling.cmake b/cmake/Modules/CMakeFlagsHandling.cmake
index 508c3860b..5de3a0716 100644
--- a/cmake/Modules/CMakeFlagsHandling.cmake
+++ b/cmake/Modules/CMakeFlagsHandling.cmake
@@ -1,69 +1,69 @@
#===============================================================================
# @file CMakeFlagsHandling.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Dec 20 2012
-# @date last modification: Tue Feb 26 2013
+# @date creation: Sun Oct 19 2014
+# @date last modification: Tue Jul 14 2015
#
# @brief Set of macros used by akantu to handle the package system
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
if(_CMAKE_FLAGS_HANDLING)
return()
endif()
set(_CMAKE_FLAGS_HANDLING TRUE)
#===============================================================================
# Compilation options handling
#===============================================================================
macro(_get_flags_message type desc)
if(${type} MATCHES "C..")
set(${desc} "Flags used by the compiler during all build types.")
elseif(${type} MATCHES "EXE_LINKER")
set(${desc} "Flags used by the linker.")
elseif(${type} MATCHES "SHARED_LINKER")
set(${desc} "Flags used by the linker during the creation of dll's.")
endif()
endmacro()
#===============================================================================
macro(add_flags type flag)
string(TOUPPER ${type} _type)
set(_var CMAKE_${_type}_FLAGS)
_get_flags_message(${_type} _desc)
string(REPLACE "${flag}" "match" _temp_var "${${_var}}")
if(NOT _temp_var MATCHES "match")
set(${_var} "${flag} ${${_var}}" CACHE STRING ${_desc} FORCE)
endif()
endmacro()
#===============================================================================
macro(remove_flags type flag)
string(TOUPPER ${type} _type)
set(_var CMAKE_${_type}_FLAGS)
_get_flags_message(${_type} _desc)
string(REPLACE "${flag} " "" ${_var} "${${_var}}")
set(${_var} "${${_var}}" CACHE STRING ${_desc} FORCE)
endmacro()
#===============================================================================
diff --git a/cmake/Modules/CMakePackagesSystem.cmake b/cmake/Modules/CMakePackagesSystem.cmake
index 7f8fb6409..a30ef09d2 100644
--- a/cmake/Modules/CMakePackagesSystem.cmake
+++ b/cmake/Modules/CMakePackagesSystem.cmake
@@ -1,861 +1,915 @@
#===============================================================================
# @file CMakePackagesSystem.cmake
#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Dec 20 2012
-# @date last modification: Wed Sep 10 2014
+# @date creation: Wed Nov 05 2014
+# @date last modification: Wed Jan 13 2016
#
# @brief Set of macros used by akantu to handle the package system
#
-# @section DESCRIPTION
+# @section LICENSE
#
-# This package defines multiple function to handle packages. This packages can
-# be of two kinds regular ones and extra_packages (ex: in akantu the LGPL part
-# is regular packages and extra packages are on Propetary license)
+# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+# (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
-# Package are loaded with the help of the command:
-# package_list_packages(<regular_package_folder>
-# [ EXTRA_PACKAGE_FOLDER <extra_package_folder> ]
-# [ SOURCE_FOLDER <source_folder>]
-# [ TEST_FOLDER <test_folder> ]
-# [ MANUAL_FOLDER <manual_folder> ]
-# )
+# 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.
#
-# This command will look for packages name like
-# <regular_package_folder>/<package>.cmake
-# OR <extra_package_folder>/<package>/package.cmake
+# 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.
#
-# A package is a cmake script that should contain at list the declaration of a
-# package
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
#
-# package_declare(<package real name>
-# [EXTERNAL] [META] [ADVANCED] [NOT_OPTIONAL]
-# [DESCRIPTION <description>] [DEFAULT <default_value>]
-# [DEPENDS <pkg> ...]
-# [BOOST_COMPONENTS <pkg> ...]
-# [EXTRA_PACKAGE_OPTIONS <opt> ...]
-# [COMPILE_FLAGS <flags>]
-# [SYSTEM <bool> [ <script_to_compile> ]])
+#===============================================================================
+
+#[=======================================================================[.rst:
+#CMakePackagesSystem
+#-------------------
+#
+#This package defines multiple function to handle packages. This packages can
+#be of two kinds regular ones and extra_packages (ex: in akantu the LGPL part
+#is regular packages and extra packages are on Propetary license)
+#
+#Package are loaded with the help of the command:
+#
+#.. command:: package_list_packages
+#
+# package_list_packages(<regular_package_folder>
+# [ EXTRA_PACKAGE_FOLDER <extra_package_folder> ]
+# [ SOURCE_FOLDER <source_folder>]
+# [ TEST_FOLDER <test_folder> ]
+# [ MANUAL_FOLDER <manual_folder> ]
+# )
+#
+# This command will look for packages name like ``<regular_package_folder>/<package>.cmake``
+# OR ``<extra_package_folder>/<package>/package.cmake``
#
-# It can also declare multiple informations:
-# source files:
-# package_declare_sources(<package real name>
-# <src1> <src2> ... <srcn>)
+#A package is a cmake script that should contain at list the declaration of a
+#package
#
-# a LaTeX documentation:
-# package_declare_documentation(<package real name>
-# <line1> <line2> ...<linen>)
+#.. command:: package_declare
#
-# LaTeX documentation files
-# package_declare_documentation_files(<package real name>
-# <file1> <file2> ... <filen>)
+# package_declare(<package real name>
+# [EXTERNAL] [META] [ADVANCED] [NOT_OPTIONAL]
+# [DESCRIPTION <description>] [DEFAULT <default_value>]
+# [DEPENDS <pkg> ...]
+# [BOOST_COMPONENTS <pkg> ...]
+# [EXTRA_PACKAGE_OPTIONS <opt> ...]
+# [COMPILE_FLAGS <flags>]
+# [SYSTEM <bool> [ <script_to_compile> ]]
+# )
#
-# Different function can also be retrieved from the package system by using the
-# different accessors
+#.. command:: package_declare_sources
+#
+# It can also declare multiple informations:
+# source files:
+#
+# package_declare_sources(<package real name>
+# <src1> <src2> ... <srcn>)
+#
+#.. command:: package_declare_documentation
+#
+# a LaTeX documentation
+# package_declare_documentation(<package real name>
+# <line1> <line2> ...<linen>)
+#
+#.. command:: package_declare_documentation_files
+#
+# LaTeX documentation files
+# package_declare_documentation_files(<package real name>
+# <file1> <file2> ... <filen>)
+#
+#Different function can also be retrieved from the package system by using the
+#different accessors
+#
+#.. command:: package_get_name
# package_get_name(<pkg> <retval>)
+#
+#.. command:: package_get_real_name
# package_get_real_name(<pkg> <retval>)
#
+#.. command:: package_get_option_name
# package_get_option_name(<pkg> <retval>)
#
+#.. command:: package_use_system
# package_use_system(<pkg> <retval>)
#
+#.. command:: package_get_nature
# package_get_nature(<pkg> <retval>)
#
+#.. command:: package_get_description
# package_get_description(<pkg> <retval>)
#
+#.. command:: package_get_filename
# package_get_filename(<pkg> <retval>)
#
+#.. command:: package_get_sources_folder
# package_get_sources_folder(<pkg> <retval>)
+#.. command:: package_get_tests_folder
# package_get_tests_folder(<pkg> <retval>)
+#.. command:: package_get_manual_folder
# package_get_manual_folder(<pkg> <retval>)
#
+#.. command:: package_get_find_package_extra_options
# package_get_find_package_extra_options(<pkg> <retval>)
#
+#.. command:: package_get_compile_flags
# package_get_compile_flags(<pkg> <retval>)
+#.. command:: package_set_compile_flags
# package_set_compile_flags(<pkg> <flag1> <flag2> ... <flagn>)
#
+#.. command:: package_get_include_dir
# package_get_include_dir(<pkg> <retval>)
+#.. command:: package_set_include_dir
# package_set_include_dir(<pkg> <inc1> <inc2> ... <incn>)
+#.. command:: package_add_include_dir
# package_add_include_dir(<pkg> <inc1> <inc2> ... <incn>)
#
+#.. command:: package_get_libraries
# package_get_libraries(<pkg> <retval>)
+#.. command:: package_set_libraries
# package_set_libraries(<pkg> <lib1> <lib2> ... <libn>)
#
+#.. command:: package_add_extra_dependency
# package_add_extra_dependency(pkg <dep1> <dep2> ... <depn>)
+#.. command:: package_rm_extra_dependency
# package_rm_extra_dependency(<pkg> <dep>)
+#.. command:: package_get_extra_dependencies
# package_get_extra_dependencies(<pkg> <retval>)
#
+#.. command:: package_is_activated
# package_is_activated(<pkg> <retval>)
+#.. command:: package_is_deactivated
# package_is_deactivated(<pkg> <retval>)
#
+#.. command:: package_get_dependencies
# package_get_dependencies(<pkg> <retval>)
+#.. command:: package_add_dependencies
# package_add_dependencies(<pkg> <dep1> <dep2> ... <depn>)
#
+#.. command:: package_on_enabled_script
# package_on_enabled_script(<pkg> <script>)
#
+#.. command:: package_get_all_source_files
# package_get_all_source_files(<srcs> <public_headers> <private_headers>)
+#.. command:: package_get_all_include_directories
# package_get_all_include_directories(<inc_dirs>)
+#.. command:: package_get_all_external_informations
# package_get_all_external_informations(<include_dir> <libraries>)
+#.. command:: package_get_all_definitions
# package_get_all_definitions(<definitions>)
+#.. command:: package_get_all_extra_dependencies
# package_get_all_extra_dependencies(<dependencies>)
+#.. command:: package_get_all_test_folders
# package_get_all_test_folders(<test_dirs>)
+#.. command:: package_get_all_documentation_files
# package_get_all_documentation_files(<doc_files>)
+#.. command:: package_get_all_activated_packages
# package_get_all_activated_packages(<activated_list>)
+#.. command:: package_get_all_deactivated_packages
# package_get_all_deactivated_packages(<deactivated_list>)
+#.. command:: package_get_all_packages
# package_get_all_packages(<packages_list>)
#
-#
-# @section LICENSE
-#
-# Copyright (©) 2014 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(CMakeParseArguments)
#===============================================================================
# Package Management
#===============================================================================
if(__CMAKE_PACKAGES_SYSTEM)
return()
endif()
set(__CMAKE_PACKAGES_SYSTEM TRUE)
if(CMAKE_VERSION VERSION_GREATER 3.1.2)
cmake_policy(SET CMP0054 NEW)
endif()
#===============================================================================
option(AUTO_MOVE_UNKNOWN_FILES
"Give to cmake the permission to move the unregistered files to the ${PROJECT_SOURCE_DIR}/tmp directory" FALSE)
mark_as_advanced(AUTO_MOVE_UNKNOWN_FILES)
include(CMakePackagesSystemGlobalFunctions)
include(CMakePackagesSystemPrivateFunctions)
# ==============================================================================
# "Public" Accessors
# ==============================================================================
# ------------------------------------------------------------------------------
# Package name
# ------------------------------------------------------------------------------
function(package_get_name pkg pkg_name)
string(TOUPPER ${PROJECT_NAME} _project)
string(REPLACE "-" "_" _str_pkg "${pkg}")
string(TOUPPER ${_str_pkg} _u_package)
set(${pkg_name} ${_project}_PKG_${_u_package} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Real name
# ------------------------------------------------------------------------------
function(package_get_real_name pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_real_name(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Option name
# ------------------------------------------------------------------------------
function(package_get_option_name pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_option_name(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Set if system package or compile external lib
# ------------------------------------------------------------------------------
function(package_use_system pkg ret)
package_get_name(${pkg} _pkg_name)
_package_use_system(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
function(package_add_third_party_script_variable pkg var)
package_get_name(${pkg} _pkg_name)
_package_add_third_party_script_variable(${_pkg_name} ${var} ${ARGN})
set(${var} ${ARGN} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Set if system package or compile external lib
# ------------------------------------------------------------------------------
function(package_add_to_export_list pkg)
package_get_name(${pkg} _pkg_name)
_package_add_to_export_list(${_pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Nature
# ------------------------------------------------------------------------------
function(package_get_nature pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_nature(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Description
# ------------------------------------------------------------------------------
function(package_get_description pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_description(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Package file name
# ------------------------------------------------------------------------------
function(package_get_filename pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_filename(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Source files
# ------------------------------------------------------------------------------
function(package_get_source_files pkg ret_srcs ret_pub ret_priv)
package_get_name(${pkg} _pkg_name)
_package_get_source_files(${_pkg_name} _tmp_srcs _tmp_pub _tmp_priv)
set(${ret_srcs} ${_tmp_srcs} PARENT_SCOPE)
set(${ret_pub} ${_tmp_pub} PARENT_SCOPE)
set(${ret_priv} ${_tmp_pric} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Source folder
# ------------------------------------------------------------------------------
function(package_get_sources_folder pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_sources_folder(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Test folder
# ------------------------------------------------------------------------------
function(package_get_tests_folder pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_tests_folder(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Manual folder
# ------------------------------------------------------------------------------
function(package_get_manual_folder pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_manual_folder(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Extra option for the find_package
# ------------------------------------------------------------------------------
function(package_get_find_package_extra_options pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_find_package_extra_options(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
function(package_set_find_package_extra_options pkg)
package_get_name(${pkg} _pkg_name)
_package_set_find_package_extra_options(${_pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Compilation flags
# ------------------------------------------------------------------------------
function(package_get_compile_flags pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_compile_flags(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
function(package_set_compile_flags pkg)
package_get_name(${pkg} _pkg_name)
_package_set_compile_flags(${_pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Include dir
# ------------------------------------------------------------------------------
function(package_get_include_dir pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_include_dir(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
function(package_set_include_dir pkg)
package_get_name(${pkg} _pkg_name)
_package_set_include_dir(${_pkg_name} ${ARGN})
endfunction()
function(package_add_include_dir pkg)
package_get_name(${pkg} _pkg_name)
_package_add_include_dir(${_pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Libraries
# ------------------------------------------------------------------------------
function(package_get_libraries pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_libraries(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
function(package_set_libraries pkg)
package_get_name(${pkg} _pkg_name)
_package_set_libraries(${_pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Extra dependencies like custom commands of ExternalProject
# ------------------------------------------------------------------------------
function(package_add_extra_dependency pkg)
package_get_name(${pkg} _pkg_name)
_package_add_extra_dependency(${_pkg_name} ${ARGN})
endfunction()
function(package_rm_extra_dependency pkg dep)
package_get_name(${pkg} _pkg_name)
_package_rm_extra_dependency(${_pkg_name} ${dep})
endfunction()
function(package_get_extra_dependencies pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_extra_dependencies(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Activate/deactivate
# ------------------------------------------------------------------------------
function(package_is_activated pkg ret)
package_get_name(${pkg} _pkg_name)
_package_is_activated(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
function(package_is_deactivated pkg ret)
package_get_name(${pkg} _pkg_name)
_package_is_deactivated(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Direct dependencies
# ------------------------------------------------------------------------------
function(package_get_dependencies pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_dependencies(${_pkg_name} _tmp_name)
_package_get_real_name(${_tmp_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
function(package_add_dependencies pkg)
package_get_name(${pkg} _pkg_name)
foreach(_dep ${ARGN})
package_get_name(${_dep} _dep_pkg_name)
list(APPEND _tmp_deps ${_dep_pkg_name})
endforeach()
_package_add_dependencies(${_pkg_name} ${_tmp_deps})
endfunction()
# ------------------------------------------------------------------------------
# Documentation related functions
# ------------------------------------------------------------------------------
function(package_declare_documentation pkg)
package_get_name(${pkg} _pkg_name)
_package_set_documentation(${_pkg_name} ${ARGN})
endfunction()
function(package_declare_documentation_files pkg)
package_get_name(${pkg} _pkg_name)
_package_set_documentation_files(${_pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Set any user variables needed
# ------------------------------------------------------------------------------
function(package_set_variable variable pkg)
package_get_name(${pkg} _pkg_name)
_package_set_variable(${variable} ${_pkg_name} ${ARGN})
endfunction()
macro(package_get_variable variable pkg value)
package_get_name(${pkg} _pkg_name)
_package_get_variable(${variable} ${_pkg_name} _value_tmp)
set(${value} ${_value_tmp} PARENT_SCOPE)
endmacro()
# ==============================================================================
# Global accessors
# ==============================================================================
# ------------------------------------------------------------------------------
# get the list of source files
# ------------------------------------------------------------------------------
function(package_get_all_source_files SRCS PUBLIC_HEADERS PRIVATE_HEADERS)
string(TOUPPER ${PROJECT_NAME} _project)
unset(_tmp_srcs)
unset(_tmp_public_headers)
unset(_tmp_private_headers)
package_get_all_activated_packages(_activated_list)
foreach(_pkg_name ${_activated_list})
_package_get_source_files(${_pkg_name}
_pkg_srcs
_pkg_public_headers
_pkg_private_headers
)
list(APPEND _tmp_srcs ${_pkg_srcs})
list(APPEND _tmp_public_headers ${_pkg_public_headers})
list(APPEND _tmp_private_headers ${_pkg_private_headers})
endforeach()
set(${SRCS} ${_tmp_srcs} PARENT_SCOPE)
set(${PUBLIC_HEADERS} ${_tmp_public_headers} PARENT_SCOPE)
set(${PRIVATE_HEADERS} ${_tmp_private_headers} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Get include directories
# ------------------------------------------------------------------------------
function(package_get_all_include_directories inc_dirs)
set(_tmp)
package_get_all_activated_packages(_activated_list)
foreach(_pkg_name ${_activated_list})
foreach(_type SRCS PUBLIC_HEADERS PRIVATE_HEADERS)
foreach(_file ${${_pkg_name}_${_type}})
get_filename_component(_path "${_file}" PATH)
list(APPEND _tmp "${_path}")
endforeach()
endforeach()
endforeach()
if(_tmp)
list(REMOVE_DUPLICATES _tmp)
endif()
set(${inc_dirs} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Get external libraries informations
# ------------------------------------------------------------------------------
function(package_get_all_external_informations INCLUDE_DIR LIBRARIES)
_package_get_variable_for_activated(INCLUDE_DIR tmp_INCLUDE_DIR)
_package_get_variable_for_activated(LIBRARIES tmp_LIBRARIES)
set(${INCLUDE_DIR} ${tmp_INCLUDE_DIR} PARENT_SCOPE)
set(${LIBRARIES} ${tmp_LIBRARIES} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Get export list for all activated packages
# ------------------------------------------------------------------------------
function(package_get_all_export_list export_list)
_package_get_variable_for_activated(EXPORT_LIST _tmp)
set(${export_list} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Get definitions like external projects
# ------------------------------------------------------------------------------
function(package_get_all_definitions definitions)
_package_get_variable_for_activated(OPTION_NAME _tmp)
set(${definitions} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Get extra dependencies like external projects
# ------------------------------------------------------------------------------
function(package_get_all_extra_dependencies deps)
_package_get_variable_for_activated(EXTRA_DEPENDENCY _tmp)
set(${deps} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Get extra infos
# ------------------------------------------------------------------------------
function(package_get_all_test_folders TEST_DIRS)
_package_get_variable_for_activated(TEST_FOLDER _tmp)
set(${TEST_DIRS} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Documentation informations
# ------------------------------------------------------------------------------
function(package_get_all_documentation_files doc_files)
set(_tmp_DOC_FILES)
package_get_all_activated_packages(_activated_list)
foreach(_pkg_name ${_activated_list})
_package_get_manual_folder(${_pkg_name} _doc_dir)
_package_get_documentation_files(${_pkg_name} _doc_files)
foreach(_doc_file ${_doc_files})
list(APPEND _tmp_DOC_FILES ${_doc_dir}/${_doc_file})
endforeach()
endforeach()
if(_tmp_DOC_FILES)
list(REMOVE_DUPLICATES _tmp_DOC_FILES)
endif()
set(${doc_files} ${_tmp_DOC_FILES} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# List packages
# ------------------------------------------------------------------------------
function(package_get_all_activated_packages activated_list)
package_get_project_variable(ACTIVATED_PACKAGE_LIST _activated_list)
set(${activated_list} ${_activated_list} PARENT_SCOPE)
endfunction()
function(package_get_all_deactivated_packages deactivated_list)
package_get_project_variable(DEACTIVATED_PACKAGE_LIST _deactivated_list)
set(${deactivated_list} ${_deactivated_list} PARENT_SCOPE)
endfunction()
function(package_get_all_packages packages_list)
package_get_project_variable(ALL_PACKAGES_LIST _packages_list)
set(${packages_list} ${_packages_list} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Callbacks
# ------------------------------------------------------------------------------
function(package_on_enabled_script pkg script)
package_get_name(${pkg} _pkg_name)
_package_on_enable_script(${_pkg_name} "${script}")
endfunction()
# ------------------------------------------------------------------------------
# list all the packages in the PACKAGE_FOLDER
# extra packages can be given with an EXTRA_PACKAGE_FOLDER
# <package_folder>/<package>.cmake
#
# Extra packages folder structure
# <extra_package_folder>/<package>/package.cmake
# /src
# /test
# /manual
#
# ------------------------------------------------------------------------------
function(package_list_packages PACKAGE_FOLDER)
cmake_parse_arguments(_opt_pkg
""
"SOURCE_FOLDER;EXTRA_PACKAGES_FOLDER;TEST_FOLDER;MANUAL_FOLDER"
""
${ARGN})
string(TOUPPER ${PROJECT_NAME} _project)
# Cleaning some states to start correctly
package_get_all_packages(_already_loaded_pkg)
foreach(_pkg_name ${_already_loaded_pkg})
_package_unset_extra_dependencies(${_pkg_name})
_package_unset_dependencies(${_pkg_name})
_package_unset_activated(${_pkg_name})
endforeach()
if(_opt_pkg_SOURCE_FOLDER)
set(_src_folder "${_opt_pkg_SOURCE_FOLDER}")
else()
set(_src_folder "src/")
endif()
get_filename_component(_abs_src_folder ${_src_folder} ABSOLUTE)
if(_opt_pkg_TEST_FOLDER)
set(_test_folder "${_opt_pkg_TEST_FOLDER}")
else()
set(_test_folder "test/")
endif()
if(_opt_pkg_MANUAL_FOLDER)
set(_manual_folder "${_opt_pkg_MANUAL_FOLDER}")
else()
set(_manual_folder "doc/manual")
endif()
get_filename_component(_abs_test_folder ${_test_folder} ABSOLUTE)
get_filename_component(_abs_manual_folder ${_manual_folder} ABSOLUTE)
# check all the packages in the <package_folder>
file(GLOB _package_list "${PACKAGE_FOLDER}/*.cmake")
set(_package_files)
foreach(_pkg ${_package_list})
get_filename_component(_basename ${_pkg} NAME)
if(NOT _basename MATCHES "^\\.#.*")
list(APPEND _package_files ${_basename})
endif()
endforeach()
if(_package_files)
list(SORT _package_files)
endif()
# check all packages
set(_packages_list_all)
foreach(_pkg_file ${_package_files})
string(REGEX REPLACE "[0-9]+_" "" _pkg_file_stripped ${_pkg_file})
string(REGEX REPLACE "\\.cmake" "" _pkg ${_pkg_file_stripped})
set(_current_src_folder "${_abs_src_folder}" CACHE INTERNAL "" FORCE)
set(_current_test_folder "${_abs_test_folder}" CACHE INTERNAL "" FORCE)
set(_current_manual_folder "${_abs_manual_folder}" CACHE INTERNAL "" FORCE)
include("${PACKAGE_FOLDER}/${_pkg_file}")
unset(_current_src_folder CACHE)
unset(_current_test_folder CACHE)
unset(_current_manual_folder CACHE)
endforeach()
# check the extra_packages if they exists
if(_opt_pkg_EXTRA_PACKAGES_FOLDER)
file(GLOB _extra_package_list RELATIVE
"${_opt_pkg_EXTRA_PACKAGES_FOLDER}" "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/*")
foreach(_pkg ${_extra_package_list})
if(EXISTS "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/package.cmake")
package_get_name(${_pkg} _pkg_name)
_package_set_filename(${_pkg_name}
"${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/package.cmake")
set(_current_src_folder "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/src" CACHE INTERNAL "" FORCE)
if(EXISTS "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/test")
set(_current_test_folder "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/test" CACHE INTERNAL "" FORCE)
endif()
if(EXISTS "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/manual")
set(_current_manual_folder "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/manual" CACHE INTERNAL "" FORCE)
endif()
list(APPEND _extra_pkg_src_folders "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/src")
include("${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/package.cmake")
unset(_current_src_folder CACHE)
unset(_current_test_folder CACHE)
unset(_current_manual_folder CACHE)
endif()
endforeach()
endif()
_package_build_rdependencies()
_package_load_packages()
_package_check_files_exists()
_package_check_files_registered(${_abs_src_folder} ${_extra_pkg_src_folders})
# Load boost components if boost was loaded
package_is_activated(Boost _ret)
if(_ret)
_package_load_boost_components()
endif()
endfunction()
# ------------------------------------------------------------------------------
# macro to include internal/external packages packages
# package_declare(<package real name>
# [EXTERNAL] [META] [ADVANCED] [NOT_OPTIONAL]
# [DESCRIPTION <description>] [DEFAULT <default_value>]
# [DEPENDS <pkg> ...]
# [BOOST_COMPONENTS <pkg> ...]
# [EXTRA_PACKAGE_OPTIONS <opt> ...]
# [COMPILE_FLAGS <flags>]
# [SYSTEM <bool> [ <script_to_compile> ]])
# ------------------------------------------------------------------------------
function(package_declare pkg)
package_get_name(${pkg} _pkg_name)
_package_set_real_name(${_pkg_name} ${pkg})
_package_set_filename(${_pkg_name} "${CMAKE_CURRENT_LIST_FILE}")
_package_set_sources_folder(${_pkg_name} "${_current_src_folder}")
if(_current_test_folder)
_package_set_tests_folder(${_pkg_name} "${_current_test_folder}")
endif()
if(_current_manual_folder)
_package_set_manual_folder(${_pkg_name} "${_current_manual_folder}")
endif()
package_get_project_variable(ALL_PACKAGES_LIST _tmp_pkg_list)
list(APPEND _tmp_pkg_list ${_pkg_name})
list(REMOVE_DUPLICATES _tmp_pkg_list)
package_set_project_variable(ALL_PACKAGES_LIST ${_tmp_pkg_list})
cmake_parse_arguments(_opt_pkg
"EXTERNAL;NOT_OPTIONAL;META;ADVANCED"
"DEFAULT;DESCRIPTION"
"DEPENDS;EXTRA_PACKAGE_OPTIONS;COMPILE_FLAGS;BOOST_COMPONENTS;SYSTEM"
${ARGN})
if(_opt_pkg_UNPARSED_ARGUMENTS)
message("You gave to many arguments while registering the package ${pkg} \"${_opt_pkg_UNPARSED_ARGUMENTS}\"")
endif()
# set the nature
if(_opt_pkg_EXTERNAL)
_package_set_nature(${_pkg_name} "external")
elseif(_opt_pkg_META)
_package_set_nature(${_pkg_name} "meta")
else()
_package_set_nature(${_pkg_name} "internal")
endif()
_package_declare_option(${_pkg_name})
# set description
if(_opt_pkg_DESCRIPTION)
_package_set_description(${_pkg_name} ${_opt_pkg_DESCRIPTION})
else()
_package_set_description(${_pkg_name} "")
endif()
_package_get_option_name(${_pkg_name} _option_name)
_package_get_description(${_pkg_name} _description)
# get the default value
if(DEFINED _opt_pkg_DEFAULT)
set(_default ${_opt_pkg_DEFAULT})
else()
if(_opt_pkg_NOT_OPTIONAL)
set(_default ON)
else()
set(_default OFF)
endif()
endif()
# set the option if needed
if(_opt_pkg_NOT_OPTIONAL)
_package_get_nature(${_pkg_name} _nature)
_package_set_nature(${_pkg_name} "${_nature}_not_optional")
set(${_option_name} ${_default} CACHE INTERNAL "${_description}" FORCE)
else()
option(${_option_name} "${_description}" ${_default})
if(_opt_pkg_ADVANCED OR _opt_pkg_EXTERNAL)
mark_as_advanced(${_option_name})
endif()
endif()
# Set the option for third-partie that can be compiled as an ExternalProject
if(DEFINED _opt_pkg_SYSTEM)
list(LENGTH _opt_pkg_SYSTEM _length)
list(GET _opt_pkg_SYSTEM 0 _bool)
_package_set_system_option(${_pkg_name} ${_bool})
if(_length GREATER 1)
list(GET _opt_pkg_SYSTEM 1 _script)
_package_set_system_script(${_pkg_name} ${_script})
endif()
endif()
# set the dependecies
if(_opt_pkg_DEPENDS)
set(_depends)
foreach(_dep ${_opt_pkg_DEPENDS})
package_get_name(${_dep} _dep_pkg_name)
list(APPEND _depends ${_dep_pkg_name})
endforeach()
_package_add_dependencies(${_pkg_name} ${_depends})
endif()
# keep the extra option for the future find package
if(_opt_pkg_EXTRA_PACKAGE_OPTIONS)
_package_set_find_package_extra_options(${_pkg_name} "${_opt_pkg_EXTRA_PACKAGE_OPTIONS}")
endif()
# register the compilation flags
if(_opt_pkg_COMPILE_FLAGS)
_package_set_compile_flags(${_pkg_name} "${_opt_pkg_COMPILE_FLAGS}")
endif()
# set the boost dependencies
if(_opt_pkg_BOOST_COMPONENTS)
_package_set_boost_component_needed(${_pkg_name} "${_opt_pkg_BOOST_COMPONENTS}")
endif()
endfunction()
# ------------------------------------------------------------------------------
# declare the source files of a given package
#
# package_declare_sources(<package> <list of sources>
# SOURCES <source file> ...
# PUBLIC_HEADER <header file> ...
# PRIVATE_HEADER <header file> ...)
# ------------------------------------------------------------------------------
function(package_declare_sources pkg)
package_get_name(${pkg} _pkg_name)
# get 3 lists, if none of the options given try to distinguish the different lists
cmake_parse_arguments(_opt_pkg
""
""
"SOURCES;PUBLIC_HEADERS;PRIVATE_HEADERS"
${ARGN})
set(_tmp_srcs ${_opt_pkg_SOURCES})
set(_tmp_pub_hdrs ${_opt_pkg_PUBLIC_HEADER})
set(_tmp_pri_hdrs ${_opt_pkg_PRIVATE_HEADERS})
foreach(_file ${_opt_pkg_UNPARSED_ARGUMENTS})
if(${_file} MATCHES ".*inline.*\\.cc")
list(APPEND _tmp_pub_hdrs ${_file})
elseif(${_file} MATCHES ".*\\.h+")
list(APPEND _tmp_pub_hdrs ${_file})
else()
list(APPEND _tmp_srcs ${_file})
endif()
endforeach()
_package_get_sources_folder(${_pkg_name} _src_folder)
foreach(_type _srcs _pub_hdrs _pri_hdrs)
set(${_type})
foreach(_file ${_tmp${_type}})
# get the full name
list(APPEND ${_type} "${_src_folder}/${_file}")
endforeach()
endforeach()
set(${_pkg_name}_SRCS "${_srcs}"
CACHE INTERNAL "List of sources files" FORCE)
set(${_pkg_name}_PUBLIC_HEADERS "${_pub_hdrs}"
CACHE INTERNAL "List of public header files" FORCE)
set(${_pkg_name}_PRIVATE_HEADERS "${_pri_hdrs}"
CACHE INTERNAL "List of private header files" FORCE)
endfunction()
diff --git a/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake b/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
index b457ccc27..cbbbb3f9f 100644
--- a/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
+++ b/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
@@ -1,98 +1,100 @@
#===============================================================================
-# @file CMakePackagesSystem.cmake
+# @file CMakePackagesSystemGlobalFunctions.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Sat Jul 18 2015
+# @date last modification: Mon Dec 07 2015
+#
# @brief Set of macros used by the package system to set internal variables
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
-
# ==============================================================================
# Package system meta functions
# ==============================================================================
function(package_set_project_variable variable)
string(TOUPPER ${PROJECT_NAME} _u_project)
set(${_u_project}_${variable} "${ARGN}" CACHE INTERNAL "" FORCE)
endfunction()
function(package_get_project_variable variable value_out)
string(TOUPPER ${PROJECT_NAME} _u_project)
set(${value_out} ${${_u_project}_${variable}} PARENT_SCOPE)
endfunction()
# ==============================================================================
function(_package_set_variable variable pkg_name)
set(${pkg_name}_${variable} ${ARGN} CACHE INTERNAL "" FORCE)
endfunction()
function(_package_get_variable variable pkg_name value)
#unset(${value} PARENT_SCOPE)
if(DEFINED ${pkg_name}_${variable})
set(${value} ${${pkg_name}_${variable}} PARENT_SCOPE)
elseif(DEFINED ARGN)
set(${value} ${ARGN} PARENT_SCOPE)
else()
set(${value} PARENT_SCOPE)
endif()
endfunction()
# ==============================================================================
function(_package_variable_unset variable pkg_name)
unset(${pkg_name}_${variable} CACHE)
endfunction()
# ==============================================================================
function(_package_add_to_variable variable pkg_name)
_package_get_variable(${variable} ${pkg_name} _tmp_list)
list(APPEND _tmp_list ${ARGN})
if(_tmp_list)
list(REMOVE_DUPLICATES _tmp_list)
endif()
_package_set_variable(${variable} ${pkg_name} ${_tmp_list})
endfunction()
function(_package_remove_from_variable variable pkg_name value)
_package_get_variable(${variable} ${pkg_name} _tmp_list)
list(LENGTH _tmp_list _length)
if(_length GREATER 0)
list(REMOVE_ITEM _tmp_list ${value})
_package_set_variable(${variable} ${pkg_name} ${_tmp_list})
endif()
endfunction()
# ==============================================================================
function(_package_get_variable_for_activated variable values)
set(_list_values)
package_get_all_activated_packages(_activated_list)
foreach(_pkg_name ${_activated_list})
_package_get_variable(${variable} ${_pkg_name} _value)
list(APPEND _list_values ${_value})
endforeach()
if (_list_values)
list(REMOVE_DUPLICATES _list_values)
endif()
set(${values} ${_list_values} PARENT_SCOPE)
endfunction()
# ==============================================================================
diff --git a/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake b/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
index 7f8ced8c8..50542b5c3 100644
--- a/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
+++ b/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
@@ -1,875 +1,878 @@
#===============================================================================
-# @file CMakePackagesSystem.cmake
+# @file CMakePackagesSystemPrivateFunctions.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Sat Jul 18 2015
+# @date last modification: Mon Nov 16 2015
+#
# @brief Set of macros used by the package system, internal functions
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
# ==============================================================================
# "Private" Accessors
# ==============================================================================
# ------------------------------------------------------------------------------
# Real name
# ------------------------------------------------------------------------------
function(_package_get_real_name pkg_name real_name)
set(${real_name} ${${pkg_name}} PARENT_SCOPE)
endfunction()
function(_package_set_real_name pkg_name real_name)
set(${pkg_name} ${real_name} CACHE INTERNAL "" FORCE)
endfunction()
# ------------------------------------------------------------------------------
# Option name
# ------------------------------------------------------------------------------
function(_package_declare_option pkg_name)
string(TOUPPER "${PROJECT_NAME}" _project)
_package_get_real_name(${pkg_name} _real_name)
string(TOUPPER "${_real_name}" _u_package)
_package_get_nature(${pkg_name} _nature)
if(${_nature} MATCHES "internal" OR ${_nature} MATCHES "meta")
set(_opt_name ${_project}_${_u_package})
elseif(${_nature} MATCHES "external")
set(_opt_name ${_project}_USE_${_u_package})
else()
set(_opt_name UNKNOWN_NATURE_${_project}_${_u_package})
endif()
_package_set_variable(OPTION_NAME ${pkg_name} ${_opt_name})
endfunction()
function(_package_get_option_name pkg_name opt_name)
_package_get_variable(OPTION_NAME ${pkg_name} _opt_name)
set(${opt_name} ${_opt_name} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Set if system package or compile external lib
# ------------------------------------------------------------------------------
function(_package_set_system_option pkg_name default)
string(TOUPPER "${PROJECT_NAME}" _project)
_package_get_real_name(${pkg_name} _real_name)
string(TOUPPER "${_real_name}" _u_package)
option(${_project}_USE_SYSTEM_${_u_package}
"Should akantu compile the third-party: \"${_real_name}\"" ${default})
mark_as_advanced(${_project}_USE_SYSTEM_${_u_package})
endfunction()
function(_package_use_system pkg_name use)
string(TOUPPER "${PROJECT_NAME}" _project)
_package_get_real_name(${pkg_name} _real_name)
string(TOUPPER "${_real_name}" _u_package)
if(DEFINED ${_project}_USE_SYSTEM_${_u_package})
set(${use} ${${_project}_USE_SYSTEM_${_u_package}} PARENT_SCOPE)
else()
set(${use} TRUE PARENT_SCOPE)
endif()
endfunction()
function(_package_set_system_script pkg_name script)
_package_set_variable(COMPILE_SCRIPT ${pkg_name} "${script}")
endfunction()
function(_package_add_third_party_script_variable pkg_name var)
_package_set_variable(VARIABLE_${var} ${pkg_name} "${ARGN}")
set(${var} ${ARGN} PARENT_SCOPE)
endfunction()
function(_package_load_third_party_script pkg_name)
if(${pkg_name}_COMPILE_SCRIPT)
# set the stored variable
get_cmake_property(_all_vars VARIABLES)
foreach(_var ${_all_vars})
if(_var MATCHES "^${pkg_name}_VARIABLE_.*")
string(REPLACE "${pkg_name}_VARIABLE_" "" _orig_var "${_var}")
set(${_orig_var} ${${_var}})
endif()
endforeach()
_package_get_real_name(${pkg_name} _name)
string(TOUPPER "${_name}" _u_name)
_package_get_option_name(${pkg_name} _opt_name)
if(${_opt_name}_VERSION)
set(_version "${${_opt_name}_VERSION}")
set(${_u_name}_VERSION "${_version}" CACHE INTERNAL "" FORCE)
elseif(${_u_name}_VERSION)
set(_version "${${_u_name}_VERSION}")
endif()
# load the script
include(ExternalProject)
include(${${pkg_name}_COMPILE_SCRIPT})
if(${_u_name}_LIBRARIES)
_package_set_libraries(${pkg_name} ${${_u_name}_LIBRARIES})
list(APPEND _required_vars ${_u_name}_LIBRARIES)
endif()
if(${_u_name}_INCLUDE_DIR)
_package_set_include_dir(${pkg_name} ${${_u_name}_INCLUDE_DIR})
list(APPEND _required_vars ${_u_name}_INCLUDE_DIR)
endif()
include(FindPackageHandleStandardArgs)
if(CMAKE_VERSION VERSION_GREATER 2.8.12)
find_package_handle_standard_args(${_name}
REQUIRED_VARS ${_required_vars}
VERSION_VAR _version
FAIL_MESSAGE "Something was not configured by a the third-party script for ${_name}"
)
else()
find_package_handle_standard_args(${_name}
"Something was not configured by a the third-party script for ${_name}"
${_required_vars}
)
endif()
endif()
set(${pkg_name}_USE_SYSTEM_PREVIOUS FALSE CACHE INTERNAL "" FORCE)
endfunction()
# ------------------------------------------------------------------------------
# Nature
# ------------------------------------------------------------------------------
function(_package_set_nature pkg_name nature)
_package_set_variable(NATURE ${pkg_name} ${nature})
endfunction()
function(_package_get_nature pkg_name nature)
_package_get_variable(NATURE ${pkg_name} _nature "unknown")
set(${nature} ${_nature} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Description
# ------------------------------------------------------------------------------
function(_package_set_description pkg_name desc)
_package_set_variable(DESC ${pkg_name} ${desc})
endfunction()
function(_package_get_description pkg_name desc)
_package_get_variable(DESC ${pkg_name} _desc "No description set for the package ${${pkg_name}} (${pkg_name})")
set(${desc} ${_desc} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Package file name
# ------------------------------------------------------------------------------
function(_package_set_filename pkg_name file)
_package_set_variable(FILE ${pkg_name} ${file})
endfunction()
function(_package_get_filename pkg_name file)
_package_get_variable(FILE ${pkg_name} _file "No filename set for the package ${${pkg_name}}")
set(${file} ${_file} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Source folder
# ------------------------------------------------------------------------------
function(_package_set_sources_folder pkg_name src_folder)
_package_set_variable(SRC_FOLDER ${pkg_name} ${src_folder})
endfunction()
function(_package_get_sources_folder pkg_name src_folder)
_package_get_variable(SRC_FOLDER ${pkg_name} _src_folder)
set(${src_folder} ${_src_folder} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Test folder
# ------------------------------------------------------------------------------
function(_package_set_tests_folder pkg_name test_folder)
_package_set_variable(TEST_FOLDER ${pkg_name} ${test_folder})
endfunction()
function(_package_get_tests_folder pkg_name test_folder)
_package_get_variable(TEST_FOLDER ${pkg_name} _test_folder)
set(${test_folder} ${_test_folder} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Manual folder
# ------------------------------------------------------------------------------
function(_package_set_manual_folder pkg_name manual_folder)
_package_set_variable(MANUAL_FOLDER ${pkg_name} ${manual_folder})
endfunction()
function(_package_get_manual_folder pkg_name manual_folder)
_package_get_variable(MANUAL_FOLDER ${pkg_name} _manual_folder)
set(${manual_folder} ${_manual_folder} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Extra option for the find_package
# ------------------------------------------------------------------------------
function(_package_set_find_package_extra_options pkg_name)
_package_set_variable(FIND_PKG_OPTIONS ${pkg_name} ${ARGN})
endfunction()
function(_package_get_find_package_extra_options pkg_name options)
_package_get_variable(FIND_PKG_OPTIONS ${pkg_name} _options)
set(${options} ${_options} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Compilation flags
# ------------------------------------------------------------------------------
function(_package_set_compile_flags pkg_name)
_package_set_variable(COMPILE_FLAGS ${pkg_name} ${ARGN})
endfunction()
function(_package_get_compile_flags pkg_name flags)
_package_get_variable(COMPILE_FLAGS ${pkg_name} _flags)
set(${flags} ${_flags} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Include dir
# ------------------------------------------------------------------------------
function(_package_set_include_dir pkg_name)
_package_set_variable(INCLUDE_DIR ${pkg_name} ${ARGN})
endfunction()
function(_package_get_include_dir pkg_name include_dir)
_package_get_variable(INCLUDE_DIR ${pkg_name} _include_dir "")
set(${include_dir} ${_include_dir} PARENT_SCOPE)
endfunction()
function(_package_add_include_dir pkg_name)
_package_add_to_variable(INCLUDE_DIR ${pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Libraries
# ------------------------------------------------------------------------------
function(_package_set_libraries pkg_name)
_package_set_variable(LIBRARIES ${pkg_name} ${ARGN})
endfunction()
function(_package_get_libraries pkg_name libraries)
_package_get_variable(LIBRARIES ${pkg_name} _libraries "")
set(${libraries} ${_libraries} PARENT_SCOPE)
endfunction()
function(_package_add_libraries pkg_name)
_package_add_to_variable(LIBRARIES ${pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Extra dependencies like custom commands of ExternalProject
# ------------------------------------------------------------------------------
function(_package_add_extra_dependency pkg_name)
_package_add_to_variable(EXTRA_DEPENDENCY ${pkg_name} ${ARGN})
endfunction()
function(_package_rm_extra_dependency pkg_name dep)
_package_remove_from_variable(EXTRA_DEPENDENCY ${pkg_name} ${dep})
endfunction()
function(_package_set_extra_dependencies pkg)
_package_set_variable(EXTRA_DEPENDENCY ${pkg_name} ${ARGN})
endfunction()
function(_package_get_extra_dependencies pkg deps)
_package_get_variable(EXTRA_DEPENDENCY ${pkg_name} _deps "")
set(${deps} ${_deps} PARENT_SCOPE)
endfunction()
function(_package_unset_extra_dependencies pkg_name)
_package_variable_unset(EXTRA_DEPENDENCY ${pkg_name})
endfunction()
# ------------------------------------------------------------------------------
# Activate/deactivate
# ------------------------------------------------------------------------------
function(_package_activate pkg_name)
_package_set_variable(STATE ${pkg_name} ON)
endfunction()
function(_package_deactivate pkg_name)
_package_set_variable(STATE ${pkg_name} OFF)
endfunction()
function(_package_is_activated pkg_name act)
_package_get_variable(STATE ${pkg_name} _state OFF)
if(_state)
set(${act} TRUE PARENT_SCOPE)
else()
set(${act} FALSE PARENT_SCOPE)
endif()
endfunction()
function(_package_is_deactivated pkg_name act)
_package_get_variable(STATE ${pkg_name} _state OFF)
if(NOT _state)
set(${act} TRUE PARENT_SCOPE)
else()
set(${act} FALSE PARENT_SCOPE)
endif()
endfunction()
function(_package_unset_activated pkg_name)
_package_variable_unset(STATE ${pkg_name})
endfunction()
# ------------------------------------------------------------------------------
# Callbacks
# ------------------------------------------------------------------------------
function(_package_on_enable_script pkg_name script)
string(TOLOWER "${pkg_name}" _l_pkg_name)
set(_output_file "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_l_pkg_name}.cmake")
file(WRITE "${_output_file}"
"${script}")
_package_set_variable(CALLBACK_SCRIPT ${pkg_name} "${_output_file}")
endfunction()
function(_package_get_callback_script pkg_name filename)
_package_get_variable(CALLBACK_SCRIPT ${pkg_name} _filename NOTFOUND)
set(${filename} ${_filename} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Export list
# ------------------------------------------------------------------------------
function(_package_add_to_export_list pkg_name)
_package_add_to_variable(EXPORT_LIST ${pkg_name} ${ARGN})
endfunction()
function(_package_get_export_list pkg_name export_list)
_package_get_variable(EXPORT_LIST ${pkg_name} _export_list)
set(${export_list} ${_export_list} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Direct dependencies
# ------------------------------------------------------------------------------
function(_package_add_dependencies pkg_name)
_package_add_to_variable(DEPENDENCIES ${pkg_name} ${ARGN})
endfunction()
function(_package_get_dependencies pkg_name dependencies)
_package_get_variable(DEPENDENCIES ${pkg_name} _dependencies)
set(${dependencies} ${_dependencies} PARENT_SCOPE)
endfunction()
function(_package_unset_dependencies pkg_name)
_package_variable_unset(DEPENDENCIES ${pkg_name})
endfunction()
# ------------------------------------------------------------------------------
# Functions to handle reverse dependencies
# ------------------------------------------------------------------------------
function(_package_set_rdependencies pkg_name)
_package_set_variable(RDEPENDENCIES ${pkg_name} ${ARGN})
endfunction()
function(_package_get_rdependencies pkg_name rdependencies)
_package_get_variable(RDEPENDENCIES ${pkg_name} _rdependencies)
set(${rdependencies} ${_rdependencies} PARENT_SCOPE)
endfunction()
function(_package_add_rdependency pkg_name rdep)
# store the reverse dependency
_package_add_to_variable(RDEPENDENCIES ${pkg_name} ${rdep})
endfunction()
function(_package_remove_rdependency pkg_name rdep)
_package_remove_from_variable(RDEPENDENCIES ${pkg_name} ${rdep})
endfunction()
# ------------------------------------------------------------------------------
# Function to handle forcing dependencies (Package turn ON that enforce their
# dependencies ON)
# ------------------------------------------------------------------------------
function(_package_set_fdependencies pkg_name)
_package_set_variable(FDEPENDENCIES ${pkg_name} ${ARGN})
endfunction()
function(_package_get_fdependencies pkg_name fdependencies)
_package_get_variable(FDEPENDENCIES ${pkg_name} _fdependencies)
set(${fdependencies} ${_fdependencies} PARENT_SCOPE)
endfunction()
function(_package_add_fdependency pkg_name fdep)
# store the reverse dependency
_package_add_to_variable(FDEPENDENCIES ${pkg_name} ${fdep})
endfunction()
function(_package_remove_fdependency pkg_name fdep)
_package_remove_from_variable(FDEPENDENCIES ${pkg_name} ${fdep})
endfunction()
# ------------------------------------------------------------------------------
# Documentation related functions
# ------------------------------------------------------------------------------
function(_package_set_documentation_files pkg_name)
_package_set_variable(DOCUMENTATION_FILES ${pkg_name} ${ARGN})
endfunction()
function(_package_get_documentation_files pkg_name doc_files)
_package_get_variable(DOCUMENTATION_FILES ${pkg_name} _doc_files "")
set(${doc_files} ${_doc_files} PARENT_SCOPE)
endfunction()
function(_package_set_documentation pkg_name)
# \n replaced by && and \\ by ££ to avoid cache problems
set(_doc_str "")
foreach(_str ${ARGN})
set(_doc_str "${_doc_str}&&${_str}")
endforeach()
string(REPLACE "\\" "££" _doc_escaped "${_doc_str}")
_package_set_variable(DOCUMENTATION ${pkg_name} "${_doc_str}")
endfunction()
function(_package_get_documentation pkg_name _doc)
# \n replaced by && and \\ by ££ to avoid cache problems
_package_get_variable(DOCUMENTATION ${pkg_name} _doc_tmp "")
string(REPLACE "££" "\\" _doc_escaped "${_doc_tmp}")
string(REPLACE "&&" "\n" _doc_newlines "${_doc_escaped}")
set(${_doc} "${_doc_newlines}" PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Special boost thingy
# ------------------------------------------------------------------------------
function(_package_set_boost_component_needed pkg_name)
_package_add_to_variable(BOOST_COMPONENTS_NEEDED ${pkg_name} ${ARGN})
package_get_name(Boost _boost_pkg_name)
_package_add_dependencies(${pkg_name} ${_boost_pkg_name})
endfunction()
function(_package_get_boost_component_needed pkg_name needed)
_package_get_variable(BOOST_COMPONENTS_NEEDED ${pkg_name} _needed)
set(${needed} ${_needed} PARENT_SCOPE)
endfunction()
function(_package_load_boost_components)
string(TOUPPER ${PROJECT_NAME} _project)
_package_get_variable_for_activated(BOOST_COMPONENTS_NEEDED _boost_needed_components)
package_get_name(Boost _pkg_name)
if(_boost_needed_components)
message(STATUS "Looking for Boost liraries: ${_boost_needed_components}")
foreach(_comp ${_boost_needed_components})
find_package(Boost COMPONENTS ${_comp} QUIET)
string(TOUPPER ${_comp} _u_comp)
if(Boost_${_u_comp}_FOUND)
message(STATUS " ${_comp}: FOUND")
package_set_project_variable(BOOST_${_u_comp} TRUE)
# Generate the libraries for the package
_package_add_libraries(${_pkg_name} ${Boost_${_u_comp}_LIBRARY})
else()
message(STATUS " ${_comp}: NOT FOUND")
endif()
endforeach()
endif()
endfunction()
# ------------------------------------------------------------------------------
# get the list of source files for a given package
# ------------------------------------------------------------------------------
function(_package_get_source_files pkg_name SRCS PUBLIC_HEADERS PRIVATE_HEADERS)
string(TOUPPER ${PROJECT_NAME} _project)
set(tmp_SRCS)
set(tmp_PUBLIC_HEADERS)
set(tmp_PRIVATE_HEADERS)
foreach(_type SRCS PUBLIC_HEADERS PRIVATE_HEADERS)
foreach(_file ${${pkg_name}_${_type}})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" _rel_file "${_file}")
list(APPEND tmp_${_type} "${_rel_file}")
endforeach()
endforeach()
set(${SRCS} ${tmp_SRCS} PARENT_SCOPE)
set(${PUBLIC_HEADERS} ${tmp_PUBLIC_HEADERS} PARENT_SCOPE)
set(${PRIVATE_HEADERS} ${tmp_PRIVATE_HEADERS} PARENT_SCOPE)
endfunction()
# ==============================================================================
# Internal functions
# ==============================================================================
# ------------------------------------------------------------------------------
# Build the reverse dependencies from the dependencies
# ------------------------------------------------------------------------------
function(_package_build_rdependencies)
package_get_all_packages(_pkg_list)
# set empty lists
foreach(_pkg_name ${_pkg_list})
set(${_pkg_name}_rdeps)
endforeach()
# fill the dependencies list
foreach(_pkg_name ${_pkg_list})
_package_get_dependencies(${_pkg_name} _deps)
foreach(_dep_name ${_deps})
list(APPEND ${_dep_name}_rdeps ${_pkg_name})
endforeach()
endforeach()
# clean and set the reverse dependencies
foreach(_pkg_name ${_pkg_list})
if(${_pkg_name}_rdeps)
list(REMOVE_DUPLICATES ${_pkg_name}_rdeps)
_package_set_rdependencies(${_pkg_name} ${${_pkg_name}_rdeps})
endif()
endforeach()
endfunction()
# ------------------------------------------------------------------------------
# This function resolve the dependance order run the needed find_packages
# ------------------------------------------------------------------------------
function(_package_load_packages)
package_get_all_packages(_pkg_list)
# Activate the dependencies of activated package and generate an ordered list
# of dependencies
set(ordered_loading_list)
foreach(_pkg_name ${_pkg_list})
_package_load_dependencies_package(${_pkg_name} ordered_loading_list)
endforeach()
# Load the packages in the propoer order
foreach(_pkg_name ${ordered_loading_list})
_package_get_option_name(${_pkg_name} _option_name)
if(${_option_name})
_package_load_package(${_pkg_name})
else()
# deactivate the packages than can already be deactivated
_package_deactivate(${_pkg_name})
endif()
endforeach()
# generates the activated and unactivated lists of packages
set(_packages_activated)
set(_packages_deactivated)
foreach(_pkg_name ${_pkg_list})
_package_is_activated(${_pkg_name} _active)
if(_active)
list(APPEND _packages_activated ${_pkg_name})
else()
list(APPEND _packages_deactivated ${_pkg_name})
endif()
endforeach()
# generate the list usable by the calling code
package_set_project_variable(ACTIVATED_PACKAGE_LIST "${_packages_activated}")
package_set_project_variable(DEACTIVATED_PACKAGE_LIST "${_packages_deactivated}")
endfunction()
# ------------------------------------------------------------------------------
# This load an external package and recursively all its dependencies
# ------------------------------------------------------------------------------
function(_package_load_dependencies_package pkg_name loading_list)
# Get packages informations
_package_get_option_name(${pkg_name} _pkg_option_name)
_package_get_dependencies(${pkg_name} _dependencies)
# handle the dependencies
foreach(_dep_name ${_dependencies})
_package_get_description(${_dep_name} _dep_desc)
_package_get_option_name(${_dep_name} _dep_option_name)
_package_get_fdependencies(${_dep_name} _fdeps)
if(${_pkg_option_name})
if("${_fdeps}" STREQUAL "")
set(${_dep_name}_OLD ${${_dep_option_name}} CACHE INTERNAL "" FORCE)
endif()
# set the option to on
set(${_dep_option_name} ON CACHE BOOL "${_dep_desc}" FORCE)
# store the reverse dependency
_package_add_fdependency(${_dep_name} ${pkg_name})
else()
# check if this is the last reverse dependency
list(LENGTH _fdeps len)
list(FIND _fdeps ${pkg_name} pos)
if((len EQUAL 1) AND (NOT pos EQUAL -1))
set(${_dep_option_name} ${${_dep_name}_OLD} CACHE BOOL "${_dep_desc}" FORCE)
unset(${_dep_name}_OLD CACHE)
endif()
# remove the pkg_name form the reverse dependency
_package_remove_fdependency(${_dep_name} ${pkg_name})
endif()
# recusively load the dependencies
_package_load_dependencies_package(${_dep_name} ${loading_list})
endforeach()
# get the compile flags
_package_get_compile_flags(${pkg_name} _pkg_comile_flags)
# if package option is on add it in the list
if(${_pkg_option_name})
list(FIND ${loading_list} ${pkg_name} _pos)
if(_pos EQUAL -1)
set(_tmp_loading_list ${${loading_list}})
list(APPEND _tmp_loading_list ${pkg_name})
set(${loading_list} "${_tmp_loading_list}" PARENT_SCOPE)
endif()
#add the comilation flags if needed
if(_pkg_comile_flags)
add_flags(cxx ${_pkg_comile_flags})
endif()
else()
#remove the comilation flags if needed
if(_pkg_comile_flags)
remove_flags(cxx ${_pkg_comile_flags})
endif()
endif()
endfunction()
# ------------------------------------------------------------------------------
# Load the package if it is an external one
# ------------------------------------------------------------------------------
function(_package_load_package pkg_name)
# load the package if it is an external
_package_get_nature(${pkg_name} _nature)
if(${_nature} MATCHES "external")
_package_use_system(${pkg_name} _use_system)
set(_activated TRUE)
if(_use_system)
_package_load_external_package(${pkg_name} _activated)
else()
_package_load_third_party_script(${pkg_name})
endif()
if(_activated)
_package_activate(${pkg_name})
elseif()
_package_deactivate(${pkg_name})
endif()
else(${_nature})
_package_activate(${pkg_name})
endif()
endfunction()
# ------------------------------------------------------------------------------
# Load external packages
# ------------------------------------------------------------------------------
function(_package_load_external_package pkg_name activate)
_package_get_real_name(${pkg_name} _real_name)
string(TOUPPER ${_real_name} _u_package)
if(NOT ${pkg_name}_USE_SYSTEM_PREVIOUS)
#if system was off before clear the cache of preset variables
get_cmake_property(_all_vars VARIABLES)
foreach(_var ${_all_vars})
if(_var MATCHES "^${_u_package}_.*")
unset(${_var} CACHE)
endif()
endforeach()
set(${pkg_name}_USE_SYSTEM_PREVIOUS TRUE CACHE INTERNAL "" FORCE)
endif()
_package_get_find_package_extra_options(${pkg_name} _options)
if(_options)
cmake_parse_arguments(_opt_pkg "" "LANGUAGE" "PREFIX;FOUND;ARGS" ${_options})
if(_opt_pkg_UNPARSED_ARGUMENTS)
message("You passed too many options for the find_package related to ${${pkg_name}} \"${_opt_pkg_UNPARSED_ARGUMENTS}\"")
endif()
endif()
if(_opt_pkg_LANGUAGE)
foreach(_language ${_opt_pkg_LANGUAGE})
enable_language(${_language})
endforeach()
endif()
# find the package
find_package(${_real_name} REQUIRED ${_opt_pkg_ARGS})
# check if the package is found
if(_opt_pkg_PREFIX)
set(_package_prefix ${_opt_pkg_PREFIX})
else()
set(_package_prefix ${_u_package})
endif()
set(_act FALSE)
set(_prefix_to_consider)
if(DEFINED _opt_pkg_FOUND)
if(${_opt_pkg_FOUND})
set(_act TRUE)
set(_prefix_to_consider ${_package_prefix})
endif()
else()
foreach(_prefix ${_package_prefix})
if(${_prefix}_FOUND)
set(_act TRUE)
list(APPEND _prefix_to_consider ${_prefix})
endif()
endforeach()
endif()
if(_act)
foreach(_prefix ${_prefix_to_consider})
# Generate the include dir for the package
if(DEFINED ${_prefix}_INCLUDE_DIRS)
_package_set_include_dir(${pkg_name} ${${_prefix}_INCLUDE_DIRS})
elseif(DEFINED ${_prefix}_INCLUDE_DIR)
_package_set_include_dir(${pkg_name} ${${_prefix}_INCLUDE_DIR})
elseif(DEFINED ${_prefix}_INCLUDE_PATH)
_package_set_include_dir(${pkg_name} ${${_prefix}_INCLUDE_PATH})
endif()
# Generate the libraries for the package
if(DEFINED ${_prefix}_LIBRARIES)
_package_set_libraries(${pkg_name} ${${_prefix}_LIBRARIES})
elseif(DEFINED ${_prefix}_LIBRARY)
_package_set_libraries(${pkg_name} ${${_prefix}_LIBRARY})
endif()
endforeach()
_package_get_callback_script(${pkg_name} _script_file)
if(_script_file)
include("${_script_file}")
endif()
endif()
set(${activate} ${_act} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Sanity check functions
# ------------------------------------------------------------------------------
function(_package_check_files_exists)
set(_message FALSE)
package_get_all_packages(_pkg_list)
foreach(_pkg_name ${_pkg_list})
set(_pkg_files
${${_pkg_name}_SRCS}
${${_pkg_name}_PUBLIC_HEADERS}
${${_pkg_name}_PRIVATE_HEADERS}
)
_package_get_real_name(${_pkg_name} _real_name)
foreach(_file ${_pkg_files})
if(NOT EXISTS "${_file}")
if(NOT _message)
set(_message TRUE)
message("This file(s) is(are) present in a package but are not present on disk.")
endif()
message(" PACKAGE ${_real_name} FILE ${_file}")
endif()
endforeach()
endforeach()
if(_message)
message(SEND_ERROR "Please check the content of your packages to correct this warnings")
endif()
endfunction()
# ------------------------------------------------------------------------------
function(_package_check_files_registered)
set(_pkg_files)
package_get_all_packages(_pkg_list)
# generates a file list of registered files
foreach(_pkg_name ${_pkg_list})
list(APPEND _pkg_files
${${_pkg_name}_SRCS}
${${_pkg_name}_PUBLIC_HEADERS}
${${_pkg_name}_PRIVATE_HEADERS}
)
endforeach()
# generates the list of files in the source folders
set(_all_src_files)
foreach(_src_folder ${ARGN})
foreach(_ext "cc" "hh" "c" "h" "hpp")
file(GLOB_RECURSE _src_files "${_src_folder}/*.${_ext}")
list(APPEND _all_src_files ${_src_files})
endforeach()
endforeach()
if(_all_src_files)
list(REMOVE_DUPLICATES _all_src_files)
endif()
set(_not_registerd_files)
# check only sources files ine the source folders
foreach(_src_folder ${ARGN})
foreach(_file ${_all_src_files})
if("${_file}" MATCHES "${_src_folder}")
list(FIND _pkg_files "${_file}" _index)
if (_index EQUAL -1)
list(APPEND _not_registerd_files ${_file})
endif()
endif()
endforeach()
endforeach()
if(AUTO_MOVE_UNKNOWN_FILES)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/unknown_files)
endif()
# warn the user and move the files if needed
if(_not_registerd_files)
if(EXISTS ${PROJECT_BINARY_DIR}/missing_files_in_packages)
file(REMOVE ${PROJECT_BINARY_DIR}/missing_files_in_packages)
endif()
message("This files are present in the source folders but are not registered in any package")
foreach(_file ${_not_registerd_files})
message(" ${_file}")
if(AUTO_MOVE_UNKNOWN_FILES)
get_filename_component(_file_name ${_file} NAME)
file(RENAME ${_file} ${PROJECT_BINARY_DIR}/unknown_files/${_file_name})
endif()
file(APPEND ${PROJECT_BINARY_DIR}/missing_files_in_packages "${_file}
")
endforeach()
if(AUTO_MOVE_UNKNOWN_FILES)
message(SEND_ERROR "The files where moved in the followinf folder ${PROJECT_BINARY_DIR}/unknown_files\n
Please register them in the good package or clean the sources")
else()
message(SEND_ERROR "Please register them in the good package or clean the sources")
endif()
endif()
endfunction()
# ------------------------------------------------------------------------------
diff --git a/cmake/Modules/CMakeVersionGenerator.cmake b/cmake/Modules/CMakeVersionGenerator.cmake
index f47fe7456..72a92dd52 100644
--- a/cmake/Modules/CMakeVersionGenerator.cmake
+++ b/cmake/Modules/CMakeVersionGenerator.cmake
@@ -1,85 +1,84 @@
#===============================================================================
# @file CMakeVersionGenerator.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Dec 20 2012
-# @date last modification: Fri Jun 13 2014
+# @date creation: Sun Oct 19 2014
#
# @brief Set of macros used by akantu to handle the package system
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
if(__DEFINE_PROJECT_VERSION__)
return()
endif()
set(__DEFINE_PROJECT_VERSION__ TRUE)
macro(define_project_version)
string(TOUPPER ${PROJECT_NAME} _project)
if(EXISTS ${PROJECT_SOURCE_DIR}/VERSION)
file(STRINGS ${PROJECT_SOURCE_DIR}/VERSION ${_project}_VERSION)
if("${${_project}_VERSION}" MATCHES "^([0-9]+)")
string(REGEX REPLACE "^([0-9]+).*" "\\1" _ver_major "${${_project}_VERSION}")
set(${_project}_MAJOR_VERSION ${_ver_major})
if("${${_project}_VERSION}" MATCHES "^${_ver_major}\\.([0-9]+)")
string(REGEX REPLACE "^${_ver_major}\\.([0-9]+).*" "\\1" _ver_minor "${${_project}_VERSION}")
set(${_project}_MINOR_VERSION ${_ver_minor})
if("${${_project}_VERSION}" MATCHES "^${_ver_major}\\.${_ver_minor}\\.([0-9a-zA-Z\\-]+)")
string(REGEX REPLACE "^${_ver_major}\\.${_ver_minor}\\.([0-9a-zA-Z\\-]+).*" "\\1" _ver_build "${${_project}_VERSION}")
set(${_project}_BUILD_VERSION ${_ver_build})
endif()
endif()
endif()
# else()
# find_package(Subversion)
# if(SUBVERSION_FOUND)
# subversion_wc_info(${PROJECT_SOURCE_DIR} ${_project} ERROR_QUIET)
# if(${${_project}_WC_FOUND})
# set(${_project}_BUILD_VERSION ${${_project}_WC_REVISION})
# set(${_project}_VERSION
# "${${_project}_MAJOR_VERSION}.${${_project}_MINOR_VERSION}.${${_project}_BUILD_VERSION}"
# )
# endif()
# endif()
endif()
if(NOT ${_project}_VERSION)
set(${_project}_VERSION
"${${_project}_MAJOR_VERSION}.${${_project}_MINOR_VERSION}"
)
endif()
# Append the library version information to the library target properties
if(NOT ${_project}_NO_LIBRARY_VERSION)
message(STATUS "${PROJECT_NAME} version: ${${_project}_VERSION}")
set(${_project}_LIBRARY_PROPERTIES ${${_project}_LIBRARY_PROPERTIES}
VERSION "${${_project}_VERSION}"
SOVERSION "${${_project}_MAJOR_VERSION}.${${_project}_MINOR_VERSION}"
)
endif()
endmacro()
\ No newline at end of file
diff --git a/cmake/Modules/CorrectWindowsPaths.cmake b/cmake/Modules/CorrectWindowsPaths.cmake
index 09bcdd67d..7abdd8eec 100644
--- a/cmake/Modules/CorrectWindowsPaths.cmake
+++ b/cmake/Modules/CorrectWindowsPaths.cmake
@@ -1,14 +1,43 @@
+#===============================================================================
+# @file CorrectWindowsPaths.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Sun Oct 19 2014
+#
+# @brief
+#
+# @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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
# CorrectWindowsPaths - this module defines one macro
#
# CONVERT_CYGWIN_PATH( PATH )
# This uses the command cygpath (provided by cygwin) to convert
# unix-style paths into paths useable by cmake on windows
macro (CONVERT_CYGWIN_PATH _path)
if (WIN32)
EXECUTE_PROCESS(COMMAND cygpath.exe -m ${${_path}}
OUTPUT_VARIABLE ${_path})
string (STRIP ${${_path}} ${_path})
endif (WIN32)
endmacro (CONVERT_CYGWIN_PATH)
diff --git a/cmake/Modules/FindCppArray.cmake b/cmake/Modules/FindCppArray.cmake
index 34768497f..260351a19 100644
--- a/cmake/Modules/FindCppArray.cmake
+++ b/cmake/Modules/FindCppArray.cmake
@@ -1,35 +1,34 @@
#===============================================================================
# @file FindCppArray.cmake
#
# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
#
-# @date creation: Fri Jan 04 2013
-# @date last modification: Thu Jan 10 2013
+# @date creation: Sun Oct 19 2014
#
# @brief The find_package file for cpp-array library
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_path (CPPARRAY_INCLUDE_DIR expr.hpp PATH_SUFFIXES array)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CppArray DEFAULT_MSG CPPARRAY_INCLUDE_DIR)
diff --git a/cmake/Modules/FindEPSN.cmake b/cmake/Modules/FindEPSN.cmake
index d252334b3..d32e9e87b 100644
--- a/cmake/Modules/FindEPSN.cmake
+++ b/cmake/Modules/FindEPSN.cmake
@@ -1,56 +1,55 @@
#===============================================================================
# @file FindEPSN.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Dec 13 2010
-# @date last modification: Fri Jan 04 2013
+# @date creation: Sun Oct 19 2014
#
# @brief The find_package file for EPSN
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
#===============================================================================
find_path(EPSN_DIR EPSNConfig.cmake
PATHS $ENV{EPSN_TOP}
)
if(EPSN_DIR)
include(${EPSN_DIR}/EPSNConfig.cmake)
set(EPSN_LIB_PATH ${EPSN_DIR}/lib
${EPSN_LIBRARIES_DIR}
)
find_library(EPSN_COMMON_LIBRARY epsn_common
PATHS ${EPSN_LIB_PATH}
)
find_library(EPSN_SIMULATION_LIBRARY epsn_simulation
PATHS ${EPSN_LIB_PATH}
)
include(${EPSN_DIR}/EPSNLibraryDepends.cmake)
set(EPSN_LIBRARIES ${EPSN_SIMULATION_LIBRARY} ${EPSN_COMMON_LIBRARY})
endif(EPSN_DIR)
#===============================================================================
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(EPSN DEFAULT_MSG
EPSN_LIBRARIES EPSN_INCLUDE_DIR)
diff --git a/cmake/Modules/FindFFTW.cmake b/cmake/Modules/FindFFTW.cmake
index 4a86652de..b1e2d7996 100644
--- a/cmake/Modules/FindFFTW.cmake
+++ b/cmake/Modules/FindFFTW.cmake
@@ -1,72 +1,71 @@
#===============================================================================
# @file FindFFTW.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
-# @date creation: Thu Mar 17 2011
-# @date last modification: Mon Jul 28 2014
+# @date creation: Sun Oct 19 2014
#
-# @brief
+# @brief find_package for fftw
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
set(FFTW_VERSION "3" CACHE INTEGER "Version of FFTW required")
if (FFTW_FIND_VERSION)
set(FFTW_VERSION ${FFTW_FIND_VERSION} CACHE INTEGER "Version of FFTW required")
endif()
if (FFTW_VERSION EQUAL "2")
find_library(FFTW_LIBRARIES fftw
PATHS ${FFTW_DIR}
PATH_SUFFIXES fftw/.libs/ lib
)
find_path(FFTW_INCLUDE_PATH fftw.h
PATHS ${FFTW_DIR} $ENV{INCLUDE_PATH}
PATH_SUFFIXES include fftw
)
else()
find_library(FFTW_LIBRARIES fftw3
PATHS ENV LD_LIBRARY_PATH
)
find_library(FFTW_THREAD_LIBRARY fftw3_threads
PATHS ENV LD_LIBRARY_PATH
)
find_library(FFTW_OPENMP_LIBRARY fftw3_omp
PATHS ENV LD_LIBRARY_PATH
)
find_path(FFTW_INCLUDE_PATH fftw3.h
PATHS ENV INCLUDE_PATH
PATH_SUFFIXES include fftw
)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FFTW DEFAULT_MSG
FFTW_LIBRARIES FFTW_INCLUDE_PATH)
if(NOT FFTW_FOUND)
set(FFTW_DIR "" CACHE PATH "Location of FFTW library.")
endif(NOT FFTW_FOUND)
mark_as_advanced(FFTW_LIBRARIES FFTW_OPENMP_LIBRARY FFTW_THREAD_LIBRARY FFTW_INCLUDE_PATH FFTW_VERSION)
diff --git a/cmake/Modules/FindGMSH.cmake b/cmake/Modules/FindGMSH.cmake
index 94f8d7305..14807aaa1 100644
--- a/cmake/Modules/FindGMSH.cmake
+++ b/cmake/Modules/FindGMSH.cmake
@@ -1,82 +1,81 @@
#===============================================================================
# @file FindGMSH.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Fri Oct 15 2010
-# @date last modification: Tue Sep 09 2014
+# @date creation: Mon Dec 08 2014
#
# @brief Find gmsh and delacre the add_mesh macro
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_program(GMSH gmsh
DOC "The mesh generetor gmsh")
mark_as_advanced(GMSH)
find_package(PackageHandleStandardArgs)
find_package_handle_standard_args(GMSH DEFAULT_MSG GMSH)
#===============================================================================
macro(ADD_MESH MESH_TARGET GEO_FILE DIM ORDER)
if(GMSH_FOUND)
set(arguments
${MESH_TARGET} ${GEO_FILE} ${DIM} ${ORDER}
${ARGN}
)
cmake_parse_arguments(ADD_MESH
""
"OUTPUT"
""
${arguments}
)
set(_geo_file ${CMAKE_CURRENT_SOURCE_DIR}/${GEO_FILE})
set(_r_geo_file "${GEO_FILE}")
if(ADD_MESH_OUTPUT)
set(_msh_file ${CMAKE_CURRENT_BINARY_DIR}/${ADD_MESH_OUTPUT})
set(_r_msh_file "${ADD_MESH_OUTPUT}")
else(ADD_MESH_OUTPUT)
get_filename_component(_msh_file "${GEO_FILE}" NAME_WE)
set(_msh_file ${CMAKE_CURRENT_BINARY_DIR}/${_msh_file}.msh)
set(_r_msh_file "${_msh_file.msh}")
endif(ADD_MESH_OUTPUT)
if(EXISTS ${_geo_file})
add_custom_command(
OUTPUT ${_msh_file}
DEPENDS ${_geo_file}
COMMAND ${GMSH}
ARGS -${DIM} -order ${ORDER} -optimize -o ${_msh_file} ${_geo_file} 2>&1 > /dev/null
COMMENT "Generating the ${DIM}D mesh ${_r_msh_file} (order ${ORDER}) form the geometry ${_r_geo_file}"
)
add_custom_target(${MESH_TARGET}
DEPENDS ${_msh_file})
set_target_properties(${MESH_TARGET} PROPERTIES RESSOURCES ${_geo_file})
#else(EXISTS ${_geo_file})
# message("File ${_geo_file} not found")
endif(EXISTS ${_geo_file})
endif(GMSH_FOUND)
endmacro(ADD_MESH)
diff --git a/cmake/Modules/FindGSL.cmake b/cmake/Modules/FindGSL.cmake
index a2812c8b0..76ffa0bcd 100644
--- a/cmake/Modules/FindGSL.cmake
+++ b/cmake/Modules/FindGSL.cmake
@@ -1,54 +1,54 @@
#===============================================================================
# @file FindGSL.cmake
#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Fri Aug 10 2012
-# @date last modification: Fri Jan 04 2013
+# @date creation: Sun Oct 19 2014
#
-# @brief
+# @brief find package for gsl
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_path(GSL_INCLUDE_PATH gsl_math.h
PATHS ${GSL_DIR} ENV C_INCLUDE_PATH
PATH_SUFFIXES gsl
)
find_library(GSL_MAIN_LIBRARY NAME gsl
PATHS ${GSL_DIR} ENV LIBRARY_PATH
PATH_SUFFIXES lib
)
find_library(GSL_BLAS_LIBRARY NAME gslcblas
PATHS ${GSL_DIR} ENV LIBRARY_PATH
PATH_SUFFIXES lib
)
mark_as_advanced(GSL_INCLUDE_PATH)
mark_as_advanced(GSL_MAIN_LIBRARY NAME)
mark_as_advanced(GSL_BLAS_LIBRARY NAME)
set(GSL_LIBRARIES ${GSL_MAIN_LIBRARY} ${GSL_BLAS_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GSL DEFAULT_MSG
GSL_LIBRARIES GSL_INCLUDE_PATH)
diff --git a/cmake/Modules/FindIOHelper.cmake b/cmake/Modules/FindIOHelper.cmake
index 4eb2cf9dc..1b9698dd8 100644
--- a/cmake/Modules/FindIOHelper.cmake
+++ b/cmake/Modules/FindIOHelper.cmake
@@ -1,60 +1,59 @@
#===============================================================================
# @file FindIOHelper.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Aug 04 2010
-# @date last modification: Fri Jan 04 2013
+# @date creation: Sun Oct 19 2014
#
# @brief The find_package file for IOHelper
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
#===============================================================================
#set(IOHELPER_LIBRARY "NOTFOUND" CACHE INTERNAL "Cleared" FORCE)
find_library(IOHELPER_LIBRARY iohelper
PATHS ${IOHELPER_DIR}
PATH_SUFFIXES lib
)
find_path(IOHELPER_INCLUDE_DIR io_helper.hh
PATHS ${IOHELPER_DIR}
PATH_SUFFIXES include include/iohelper
)
#===============================================================================
mark_as_advanced(IOHELPER_LIBRARY)
mark_as_advanced(IOHELPER_INCLUDE_DIR)
#===============================================================================
find_package(ZLIB REQUIRED)
set(IOHELPER_LIBRARIES_ALL ${IOHELPER_LIBRARY} ${ZLIB_LIBRARIES})
set(IOHELPER_LIBRARIES ${IOHELPER_LIBRARIES_ALL} CACHE INTERNAL "Libraries for IOHelper" FORCE)
#===============================================================================
if(NOT IOHELPER_FOUND)
set(IOHELPER_DIR "" CACHE PATH "Location of IOHelper source directory.")
endif()
#===============================================================================
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(IOHelper DEFAULT_MSG IOHELPER_LIBRARY IOHELPER_INCLUDE_DIR)
diff --git a/cmake/Modules/FindInkscape.cmake b/cmake/Modules/FindInkscape.cmake
index eb0d2e63c..c35b302ae 100644
--- a/cmake/Modules/FindInkscape.cmake
+++ b/cmake/Modules/FindInkscape.cmake
@@ -1,93 +1,93 @@
#===============================================================================
# @file FindInkscape.cmake
#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Jan 10 2013
-# @date last modification: Thu Jan 10 2013
+# @date creation: Sun Oct 19 2014
#
-# @brief
+# @brief find_package for inkscape
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
# Module thaat checks for inkscape
#
# Sets the following variables
#
# INSCAPE: Path to inkscape to generate .png's form .svg's
#
# Provides the following functions:
#
# inkscape_generate_png_from_svg([OUTPUT_DIR <output_dir>] <pngfile1.png> [<pngfile2.png> ....])
#
# Generates pngfile1, ... from svg input files pngfile1.svg, ....
# The output directory can be specified with the option OUTPUT_DIR. If it is omitted
# the files will be generated in CMAKE_CURRENT_BINARY_DIR.
find_program(INKSCAPE inkscape DOC "Path to inkscape to generate png files from svg files")
find_program(CONVERT convert DOC "Path to convert program")
if(INKSCAPE)
set(INKSCAPE_FOUND True)
endif(INKSCAPE)
include(CMakeParseArguments)
function(inkscape_generate_png_from_svg)
if(NOT INKSCAPE)
return()
endif(NOT INKSCAPE)
cmake_parse_arguments(INKSCAPE "" "DPI" "" ${ARGN})
if(NOT INKSCAPE_DPI)
set(INKSCAPE_DPI 90)
endif(NOT INKSCAPE_DPI)
foreach(pic ${INKSCAPE_UNPARSED_ARGUMENTS})
string(REGEX REPLACE "\\.[a-zA-Z]+" ".png" output ${pic})
add_custom_command(OUTPUT ${output}
COMMAND ${INKSCAPE} --export-dpi=${INKSCAPE_DPI} -e ${output} -f ${pic}
DEPENDS ${pic}
COMMENT "Generating ${output} from ${pic}"
)
endforeach(pic)
endfunction(inkscape_generate_png_from_svg)
function(inkscape_generate_eps_from_svg)
cmake_parse_arguments(INKSCAPE "" "INPUT_DIR;OUTPUT_DIR;DPI" "" ${ARGN})
if(NOT INKSCAPE_INPUT_DIR)
set(INKSCAPE_INPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
endif(NOT INKSCAPE_INPUT_DIR)
if(NOT INKSCAPE_INPUT_DIR)
set(INKSCAPE_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif(NOT INKSCAPE_INPUT_DIR)
foreach(_pic ${INKSCAPE_UNPARSED_ARGUMENTS})
string(REGEX REPLACE "\\.[a-zA-Z]+" ".png" input "${_pic}")
string(REGEX REPLACE "\\.[a-zA-Z]+" ".svg" svginput "${_pic}")
add_custom_target(${input}
COMMAND ${INKSCAPE} --export-dpi=${INKSCAPE_DPI} -e ${input} ${CMAKE_CURRENT_SOURCE_DIR}/${svginput}
COMMENT "Generating ${INKSCAPE_OUTPUT_DIR}/${pic} from ${CMAKE_CURRENT_SOURCE_DIR}/${input}")
add_custom_command(OUTPUT ${_pic}
COMMAND ${CONVERT} ${INKSCAPE_INPUT_DIR}/${input} EPS:${_pic}
DEPENDS ${input}
COMMENT "Converting ${INKSCAPE_INPUT_DIR}/${input} to ${INKSCAPE_OUTPUT_DIR}/${_pic}"
WORKING_DIRECTORY ${INKSCAPE_OUTPUT_DIR})
endforeach(_pic ${INKSCAPE_UNPARSED_ARGUMENTS})
endfunction(inkscape_generate_eps_from_svg)
\ No newline at end of file
diff --git a/cmake/Modules/FindLAMMPS.cmake b/cmake/Modules/FindLAMMPS.cmake
index bf16c78ee..81f456ef3 100644
--- a/cmake/Modules/FindLAMMPS.cmake
+++ b/cmake/Modules/FindLAMMPS.cmake
@@ -1,68 +1,68 @@
#===============================================================================
# @file FindLAMMPS.cmake
#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Mar 17 2011
-# @date last modification: Fri Jan 04 2013
+# @date creation: Sun Oct 19 2014
#
-# @brief
+# @brief find package for lammps
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_path(LAMMPS_INCLUDE_PATH lammps.h
PATHS ${LAMMPS_DIR} ENV C_INCLUDE_PATH
PATH_SUFFIXES src
)
#if (not ${LAMMPS_ARCH})
file(GLOB ARCHS "${LAMMPS_INCLUDE_PATH}/liblmp*")
foreach(loop_var IN ITEMS ${ARCHS})
get_filename_component(loop_var ${loop_var} NAME)
string(REGEX REPLACE ".so" "" loop_var ${loop_var})
string(REGEX REPLACE "liblmp_" "" loop_var ${loop_var})
# MESSAGE ("possible archs compiled for lammps : ${loop_var}")
SET(LAMMPS_ARCH ${loop_var} CACHE INTERNAL "internal built version of lammps detection" FORCE)
# MESSAGE ("libname : lmp_${LAMMPS_ARCH}")
endforeach(loop_var)
#endif(not ${LAMMPS_ARCH})
find_library(LAMMPS_MAIN_LIBRARY NAME lmp_${LAMMPS_ARCH}
PATHS ${LAMMPS_DIR}
PATH_SUFFIXES src
)
if (NOT LAMMPS_MAIN_LIBRARY)
set(LAMMPS_DIR "" CACHE PATH "Location of LAMMPS library.")
endif (NOT LAMMPS_MAIN_LIBRARY)
find_library(LAMMPS_MEAM_LIBRARIES NAME meam
PATHS ${LAMMPS_DIR}
PATH_SUFFIXES lib/meam
)
set(LAMMPS_LIBRARIES ${LAMMPS_MAIN_LIBRARY} ${LAMMPS_MEAM_LIBRARIES})
SEPARATE_ARGUMENTS(LAMMPS_LIBRARIES)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LAMMPS DEFAULT_MSG
LAMMPS_LIBRARIES LAMMPS_INCLUDE_PATH)
\ No newline at end of file
diff --git a/cmake/Modules/FindMumps.cmake b/cmake/Modules/FindMumps.cmake
index fc2d1b504..036e58910 100644
--- a/cmake/Modules/FindMumps.cmake
+++ b/cmake/Modules/FindMumps.cmake
@@ -1,182 +1,182 @@
#===============================================================================
# @file FindMumps.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Dec 13 2010
-# @date last modification: Tue Sep 09 2014
+# @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 (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
set(_MUMPS_COMPONENTS "sequential" "parallel")
if(NOT Mumps_FIND_COMPONENTS)
set(Mumps_FIND_COMPONENTS "parallel")
endif()
#===============================================================================
enable_language(Fortran)
if("${Mumps_FIND_COMPONENTS}" STREQUAL "sequential")
set(MUMPS_PREFIX _seq)
else()
unset(MUMPS_PREFIX)
endif()
find_path(MUMPS_INCLUDE_DIR dmumps_c.h
HINTS ${MUMPS_DIR}
PATH_SUFFIXES include
)
find_library(MUMPS_LIBRARY_COMMON NAMES mumps_common${MUMPS_PREFIX}
HINTS ${MUMPS_DIR}
PATH_SUFFIXES lib
)
find_library(MUMPS_LIBRARY_PORD NAMES pord${MUMPS_PREFIX}
HINTS ${MUMPS_DIR}
PATH_SUFFIXES lib
)
foreach(_precision s d c z)
string(TOUPPER "${_precision}" _u_precision)
find_library(MUMPS_LIBRARY_${_u_precision}MUMPS NAMES ${_precision}mumps${MUMPS_PREFIX}
HINTS ${MUMPS_DIR} /usr
PATH_SUFFIXES lib
)
mark_as_advanced(MUMPS_LIBRARY_${_u_precision}MUMPS)
endforeach()
mark_as_advanced(
MUMPS_LIBRARY_COMMON
MUMPS_LIBRARY_PORD
MUMPS_INCLUDE_DIR)
#===============================================================================
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_INCLUDE_DIR
VERSION_VAR
MUMPS_VERSION)
else()
find_package_handle_standard_args(Mumps DEFAULT_MSG
MUMPS_LIBRARIES MUMPS_INCLUDE_DIR)
endif()
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 (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})
list(APPEND MUMPS_LIBRARIES_ALL
${MUMPS_LIBRARY_COMMON}
${MUMPS_LIBRARY_PORD}
pthread
${_compiler_specific}
)
if("${Mumps_FIND_COMPONENTS}" STREQUAL "parallel")
find_package(MPI REQUIRED)
list(APPEND _extra_dep_list ${MPI_Fortran_LIBRARIES})
find_package(ScaLAPACK REQUIRED)
list(APPEND _extra_dep_list ScaLAPACK)
list(APPEND MUMPS_LIBRARIES_ALL
${MPI_Fortran_LIBRARIES}
${SCALAPACK_LIBRARIES}
)
endif()
list(APPEND MUMPS_LIBRARIES_ALL
${BLAS_LIBRARIES})
if(_extra_dep_list)
set(_extra_dep ";${_extra_dep_list}")
else()
set(_extra_dep)
endif()
else()
set(MUMPS_LIBRARY_TYPE SHARED CACHE INTERNAL "" FORCE)
endif()
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}"
INTERFACE_INCLUDE_DIRECTORIES "${MUMPS_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C;Fortran"
INTERFACE_LINK_LIBRARIES "MUMPS::pord${_extra_dep}")
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()
diff --git a/cmake/Modules/FindNLopt.cmake b/cmake/Modules/FindNLopt.cmake
index 1855f4578..725dc04a9 100644
--- a/cmake/Modules/FindNLopt.cmake
+++ b/cmake/Modules/FindNLopt.cmake
@@ -1,54 +1,53 @@
#===============================================================================
# @file FindNLopt.cmake
#
# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
#
-# @date creation: Fri Jan 04 2013
-# @date last modification: Thu Jul 24 2014
+# @date creation: Sun Oct 19 2014
#
# @brief The find_package file for NLopt optimization library
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_library(NLOPT_LIBRARIES NAMES nlopt_cxx
PATHS ${NLOPT_DIR} ${NLOPT_INTERNAL_DIR}
PATH_SUFFIXES lib
)
find_path(NLOPT_INCLUDE_DIR nlopt.hpp
PATHS ${NLOPT_DIR} ${NLOPT_INTERNAL_DIR}
PATH_SUFFIXES include
)
#===============================================================================
mark_as_advanced(NLOPT_LIBRARIES)
mark_as_advanced(NLOPT_INCLUDE_DIR)
#===============================================================================
if(NOT NLOPT_FOUND)
set(NLOPT_DIR "" CACHE PATH "Location of NLOPT source directory.")
endif()
#===============================================================================
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(NLopt DEFAULT_MSG NLOPT_LIBRARIES NLOPT_INCLUDE_DIR)
diff --git a/cmake/Modules/FindNumpy.cmake b/cmake/Modules/FindNumpy.cmake
index cf839e573..2c21b0025 100644
--- a/cmake/Modules/FindNumpy.cmake
+++ b/cmake/Modules/FindNumpy.cmake
@@ -1,69 +1,71 @@
#===============================================================================
# @file FindNumpy.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Mon Nov 16 2015
+#
# @brief The find_package file for numpy
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_package(PythonInterp)
#numpy includes
if(PYTHONINTERP_FOUND)
set(_get_include "from __future__ import print_function; import numpy; print(numpy.get_include(), end='')")
set(_get_version "from __future__ import print_function; import numpy; print(numpy.version.full_version, end=''),")
execute_process(COMMAND
${PYTHON_EXECUTABLE} -c "${_get_include}"
OUTPUT_VARIABLE _numpy_include_dir
ERROR_QUIET
RESULT_VARIABLE _res)
if(_res EQUAL 0)
set(NUMPY_INCLUDE_DIR "${_numpy_include_dir}" CACHE PATH "Include directory for numpy" FORCE)
execute_process(COMMAND
${PYTHON_EXECUTABLE} -c "${_get_version}"
OUTPUT_VARIABLE _numpy_version
ERROR_QUIET
RESULT_VARIABLE _res)
if(_res EQUAL 0)
set(NUMPY_VERSION "${_numpy_version}" CACHE STRING "Version of numpy")
else()
set(NUMPY_VERSION "NUMPY_VERSION-NOTFOUND" CACHE STRING "Version of numpy")
endif()
mark_as_advanced(NUMPY_INCLUDE_DIR NUMPY_VERSION)
else()
set(NUMPY_INCLUDE_DIR "NUMPY_INCLUDE_DIR-NOTFOUND" CACHE PATH "")
endif()
endif()
#===============================================================================
include(FindPackageHandleStandardArgs)
if(CMAKE_VERSION VERSION_GREATER 2.8.12)
find_package_handle_standard_args(Numpy
REQUIRED_VARS NUMPY_INCLUDE_DIR
VERSION_VAR NUMPY_VERSION)
else()
find_package_handle_standard_args(Numpy DEFAULT_MSG
NUMPY_INCLUDE_DIR NUMPY_VERSION)
endif()
diff --git a/cmake/Modules/FindPQXX.cmake b/cmake/Modules/FindPQXX.cmake
index f5817f473..70b68fb08 100644
--- a/cmake/Modules/FindPQXX.cmake
+++ b/cmake/Modules/FindPQXX.cmake
@@ -1,61 +1,60 @@
#===============================================================================
# @file FindPQXX.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Fri Jan 13 2012
-# @date last modification: Tue Sep 09 2014
+# @date creation: Sun Oct 19 2014
#
# @brief The find_package file for PostgreSQL C++ library
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_package(PostgreSQL REQUIRED)
if(POSTGRESQL_FOUND)
find_library(PQXX_LIBRARY NAMES pqxx
HINTS ${PQXX_DIR} ENV PQXX_DIR
DOC "Location of libpqxx library"
)
find_path(PQXX_HEADER_DIR NAMES pqxx/pqxx
HINTS ${PQXX_DIR} ENV PQXX_DIR
DOC "Path to pqxx/pqxx header file. Do not include the 'pqxx' directory in this value."
)
set(PQXX_INCLUDE_DIR "${PQXX_HEADER_DIR};${POSTGRESQL_INCLUDE_DIR}" CACHE STRING "Include directories for PostgreSQL C++ library" FORCE)
set(PQXX_LIBRARIES "${PQXX_LIBRARY};${POSTGRESQL_LIBRARIES}" CACHE STRING "Link libraries for PostgreSQL C++ interface" FORCE)
mark_as_advanced(PQXX_HEADER_DIR)
mark_as_advanced(PQXX_INCLUDE_DIR)
mark_as_advanced(PQXX_LIBRARY)
mark_as_advanced(PQXX_LIBRARIES)
endif()
#===============================================================================
if(NOT PQXX_FOUND)
set(PQXX_DIR "" CACHE PATH "Help to find the location of pqxx library.")
mark_as_advanced(PQXX_FOUND)
endif()
#===============================================================================
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PQXX DEFAULT_MSG PQXX_LIBRARY PQXX_HEADER_DIR)
diff --git a/cmake/Modules/FindPTScotch.cmake b/cmake/Modules/FindPTScotch.cmake
index 4099b7a33..490803384 100644
--- a/cmake/Modules/FindPTScotch.cmake
+++ b/cmake/Modules/FindPTScotch.cmake
@@ -1,108 +1,107 @@
#===============================================================================
# @file FindPTScotch.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Tue Apr 05 2011
-# @date last modification: Fri Jan 04 2013
+# @date creation: Fri Oct 24 2014
#
# @brief The find_package file for PT-Scotch
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
#===============================================================================
#if(PTSCOTCH_DIR)
# set(PTSCOTCH_LIBRARY "NOTFOUND" CACHE INTERNAL "Cleared" FORCE)
#endif(PTSCOTCH_DIR)
find_library(PTSCOTCH_LIBRARY ptscotch
PATHS ${PTSCOTCH_DIR}
PATH_SUFFIXES src/libscotch lib
)
find_library(PTSCOTCH_LIBRARY_ERR ptscotcherr
PATHS ${PTSCOTCH_DIR}
PATH_SUFFIXES src/libscotch lib
)
find_library(PTSCOTCH_LIBRARY_ESMUMPS ptesmumps
PATHS ${PTSCOTCH_DIR}
PATH_SUFFIXES src/libscotch lib
)
find_library(PTSCOTCH_LIBRARY_METIS ptscotchmetis
PATHS ${PTSCOTCH_DIR}
PATH_SUFFIXES src/libscotch lib
)
find_library(PTSCOTCH_LIBRARY_PARMETIS ptscotchparmetis
PATHS ${PTSCOTCH_DIR}
PATH_SUFFIXES src/libscotch lib
)
find_path(PTSCOTCH_INCLUDE_PATH ptscotch.h
PATHS ${PTSCOTCH_DIR}
PATH_SUFFIXES include scotch src/libscotch include/scotch
)
#===============================================================================
mark_as_advanced(
PTSCOTCH_LIBRARY
PTSCOTCH_LIBRARY_ERR
PTSCOTCH_LIBRARY_ESMUMPS
PTSCOTCH_LIBRARY_METIS
PTSCOTCH_LIBRARY_PARMETIS
PTSCOTCH_INCLUDE_PATH)
set(PTSCOTCH_LIBRARIES_ALL ${PTSCOTCH_LIBRARY} ${PTSCOTCH_LIBRARY_ERR})
if(PTSCOTCH_LIBRARY_ESMUMPS)
set(PTSCOTCH_LIBRARIES_ALL ${PTSCOTCH_LIBRARY_ESMUMPS} ${PTSCOTCH_LIBRARIES_ALL})
endif()
if(PTSCOTCH_LIBRARY_METIS)
set(PTSCOTCH_LIBRARIES_ALL ${PTSCOTCH_LIBRARY_METIS} ${PTSCOTCH_LIBRARIES_ALL})
endif()
if(PTSCOTCH_LIBRARY_PARMETIS)
set(PTSCOTCH_LIBRARIES_ALL ${PTSCOTCH_LIBRARY_PARMETIS} ${PTSCOTCH_LIBRARIES_ALL})
endif()
set(PTSCOTCH_LIBRARIES ${PTSCOTCH_LIBRARIES_ALL} CACHE INTERNAL "Libraries for PT-Scotch" FORCE)
#===============================================================================
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PTSCOTCH DEFAULT_MSG
PTSCOTCH_LIBRARY PTSCOTCH_LIBRARY_ERR PTSCOTCH_INCLUDE_PATH)
if(PTSCOTCH_INCLUDE_PATH)
file(STRINGS ${PTSCOTCH_INCLUDE_PATH}/scotch.h PTSCOTCH_INCLUDE_CONTENT)
string(REGEX MATCH "_cplusplus" _match ${PTSCOTCH_INCLUDE_CONTENT})
if(_match)
add_definitions(-DAKANTU_PTSCOTCH_NO_EXTERN)
endif()
endif()
#===============================================================================
if(NOT PTSCOTCH_FOUND)
set(PTSCOTCH_DIR "" CACHE PATH "Location of PT-Scotch library.")
endif(NOT PTSCOTCH_FOUND)
diff --git a/cmake/Modules/FindParaDiS.cmake b/cmake/Modules/FindParaDiS.cmake
index 4ffeb0aee..e5c96454b 100644
--- a/cmake/Modules/FindParaDiS.cmake
+++ b/cmake/Modules/FindParaDiS.cmake
@@ -1,45 +1,44 @@
#===============================================================================
# @file FindParaDiS.cmake
#
#
-# @date creation: Tue Mar 29 2011
-# @date last modification: Fri Jan 04 2013
+# @date creation: Sun Oct 19 2014
#
-# @brief
+# @brief find_package for paradis
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_library(PARADIS_LIBRARIES paradis
PATHS ${PARADIS_DIR}
PATH_SUFFIXES bin)
find_path(PARADIS_INCLUDE_PATH ParadisGen.h
PATHS ${PARADIS_DIR}
PATH_SUFFIXES include
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PARADIS DEFAULT_MSG
PARADIS_LIBRARIES PARADIS_INCLUDE_PATH)
if (NOT PARADIS_FOUND)
set(PARADIS_DIR "" CACHE PATH "Location of PARADIS library")
endif(NOT PARADIS_FOUND)
\ No newline at end of file
diff --git a/cmake/Modules/FindPostgreSQL.cmake b/cmake/Modules/FindPostgreSQL.cmake
index 7821f67eb..ae8d12f16 100644
--- a/cmake/Modules/FindPostgreSQL.cmake
+++ b/cmake/Modules/FindPostgreSQL.cmake
@@ -1,46 +1,45 @@
#===============================================================================
# @file FindPostgreSQL.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Fri Jan 13 2012
-# @date last modification: Thu Nov 14 2013
+# @date creation: Sun Oct 19 2014
#
# @brief The find_package file for PostgreSQL C library
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_library(POSTGRESQL_LIBRARIES NAMES pq
PATH_SUFFIXES pgsql postgresql
PATH ENV POSTGRESQL_DIR
)
find_path(POSTGRESQL_INCLUDE_DIR NAMES libpq-fe.h
PATH_SUFFIXES pgsql postgresql
PATHS ENV POSTGRESQL_DIR
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(POSTGRESQL DEFAULT_MSG
POSTGRESQL_LIBRARIES POSTGRESQL_INCLUDE_DIR)
mark_as_advanced(POSTGRESQL_INCLUDE_DIR)
mark_as_advanced(POSTGRESQL_LIBRARIES)
diff --git a/cmake/Modules/FindQVIEW.cmake b/cmake/Modules/FindQVIEW.cmake
index 461bd7de4..1d57be6c4 100644
--- a/cmake/Modules/FindQVIEW.cmake
+++ b/cmake/Modules/FindQVIEW.cmake
@@ -1,50 +1,49 @@
#===============================================================================
# @file FindQVIEW.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Mar 17 2011
-# @date last modification: Sun Jan 06 2013
+# @date creation: Sun Oct 19 2014
#
# @brief The find_package file for libQVIEW
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_library(QVIEW_LIBRARIES NAME qview
PATHS ${QVIEW_DIR}
PATH_SUFFIXES lib
)
#===============================================================================
find_path(QVIEW_INCLUDE_DIR libqview.h
PATHS ${QVIEW_DIR}
PATH_SUFFIXES include src
)
#===============================================================================
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(QVIEW DEFAULT_MSG
QVIEW_LIBRARIES QVIEW_INCLUDE_DIR)
#===============================================================================
if(NOT QVIEW_FOUND)
set(QVIEW_DIR "" CACHE PATH "Location of QVIEW library.")
endif(NOT QVIEW_FOUND)
diff --git a/cmake/Modules/FindSIMULPACK.cmake b/cmake/Modules/FindSIMULPACK.cmake
index c28e68bf3..82c51f22c 100644
--- a/cmake/Modules/FindSIMULPACK.cmake
+++ b/cmake/Modules/FindSIMULPACK.cmake
@@ -1,118 +1,118 @@
#===============================================================================
# @file FindSIMULPACK.cmake
#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Mar 17 2011
-# @date last modification: Fri Jan 04 2013
+# @date creation: Sun Oct 19 2014
#
-# @brief
+# @brief find_package for simulpack
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_path(SIMULPACK_INCLUDE_PATH adlib.h
PATHS ${SIMULPACK_DIR} ENV C_INCLUDE_PATH
PATH_SUFFIXES include src adlib adlib-cmake
)
SET(USING_SIMULPACK_TEMPERATURE OFF CACHE BOOL "Activation of temperature within SIMULPACK plugin" )
SET(SIMULPACK_MATERIALS "-NOTFOUND" CACHE LIBRARY "" FORCE)
SET(SIMULPACK_MECHANICS "-NOTFOUND" CACHE LIBRARY "" FORCE)
SET(SIMULPACK_MESHER3D "-NOTFOUND" CACHE LIBRARY "" FORCE)
SET(SIMULPACK_UTILS "-NOTFOUND" CACHE LIBRARY "" FORCE)
SET(SIMULPACK_FEM "-NOTFOUND" CACHE LIBRARY "" FORCE)
SET(SIMULPACK_LIBMYUTILS "-NOTFOUND" CACHE LIBRARY "" FORCE)
SET(SIMULPACK_SUBDI_COLLAPSE3D "-NOTFOUND" CACHE LIBRARY "" FORCE)
SET(SIMULPACK_MESH_IO "-NOTFOUND" CACHE LIBRARY "" FORCE)
FIND_LIBRARY(SIMULPACK_PMECHANICS NAME pmechanics
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
FIND_LIBRARY(SIMULPACK_MESHER3D NAME mesher3d
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
FIND_LIBRARY(SIMULPACK_MATERIALS NAME materials
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
FIND_LIBRARY(SIMULPACK_MECHANICS NAME mechanics
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
FIND_LIBRARY(SIMULPACK_FEM NAME fem
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
FIND_LIBRARY(SIMULPACK_MYUTILS NAME myutils
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
FIND_LIBRARY(SIMULPACK_UTILS NAME utils
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
FIND_LIBRARY(SIMULPACK_SUBDI_COLLAPSE3D NAME subdi_collapse3d
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
FIND_LIBRARY(SIMULPACK_MESH_IO NAME mesh_io
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
IF (USING_SIMULPACK_TEMPERATURE)
ADD_DEFINITIONS(-DUSING_SIMULPACK_TEMPERATURE)
FIND_LIBRARY(SIMULPACK_MULTIPHYSICS NAME multiphysics
PATHS ${SIMULPACK_DIR}
PATHS ${SIMULPACK_LIB_PATH}
PATH_SUFFIXES lib
)
ENDIF (USING_SIMULPACK_TEMPERATURE)
set(SIMULPACK_LIBRARIES ${SIMULPACK_MULTIPHYSICS} ${SIMULPACK_MECHANICS} ${SIMULPACK_MESHER3D} ${SIMULPACK_UTILS} ${SIMULPACK_FEM} ${SIMULPACK_MATERIALS} ${SIMULPACK_MYUTILS} ${SIMULPACK_SUBDI_COLLAPSE3D} ${SIMULPACK_PMECHANICS} ${SIMULPACK_MESH_IO})
SEPARATE_ARGUMENTS(SIMULPACK_LIBRARIES)
#SET(SIMULPACK_INCLUDE_DIR "${SIMULPACK_SRC} ${SIMULPACK_SRC}/utils/include" CACHE STRING "simulpack includes" FORCE)
#SEPARATE_ARGUMENTS(SIMULPACK_INCLUDE_DIR)
if (NOT SIMULPACK_MECHANICS)
set(SIMULPACK_DIR "" CACHE PATH "Location of SIMULPACK main tree.")
set(SIMULPACK_LIB_PATH "" CACHE PATH "Additional path to search SimulPack libraries" )
endif(NOT SIMULPACK_MECHANICS)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SIMULPACK DEFAULT_MSG
SIMULPACK_MECHANICS SIMULPACK_MESHER3D SIMULPACK_UTILS SIMULPACK_FEM SIMULPACK_MATERIALS SIMULPACK_MYUTILS SIMULPACK_SUBDI_COLLAPSE3D SIMULPACK_PMECHANICS SIMULPACK_MESH_IO SIMULPACK_INCLUDE_PATH)
diff --git a/cmake/Modules/FindScaLAPACK.cmake b/cmake/Modules/FindScaLAPACK.cmake
index 41cecee48..b2f203f52 100644
--- a/cmake/Modules/FindScaLAPACK.cmake
+++ b/cmake/Modules/FindScaLAPACK.cmake
@@ -1,116 +1,116 @@
#===============================================================================
-# @file FindMumps.cmake
+# @file FindScaLAPACK.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Dec 13 2010
-# @date last modification: Tue Sep 09 2014
+# @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 (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_library(SCALAPACK_LIBRARY NAME scalapack
HINTS ${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})
set(_blacs_dep)
if(SCALAPACK_LIBRARY MATCHES ".*scalapack.*${CMAKE_STATIC_LIBRARY_SUFFIX}")
# 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)
find_library(BLACS_LIBRARY_F77 NAME blacsF77
HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib)
find_library(BLACS_LIBRARY NAME blacs
HINTS ${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)
endif()
diff --git a/cmake/Modules/FindScotch.cmake b/cmake/Modules/FindScotch.cmake
index b937c97d0..b73aa3cdd 100644
--- a/cmake/Modules/FindScotch.cmake
+++ b/cmake/Modules/FindScotch.cmake
@@ -1,92 +1,92 @@
#===============================================================================
# @file FindScotch.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Sep 01 2010
-# @date last modification: Tue Sep 09 2014
+# @date creation: Fri Oct 24 2014
+# @date last modification: Wed Jan 13 2016
#
# @brief The find_package file for Scotch
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
#===============================================================================
if(NOT DEFINED SCOTCH_DIR OR NOT SCOTCH_DIR)
set(SCOTCH_DIR "" CACHE PATH "Location of Scotch library.")
endif()
mark_as_advanced(SCOTCH_DIR)
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)
find_path(SCOTCH_INCLUDE_DIR scotch.h PATHS ${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()
set(SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES_ALL} CACHE INTERNAL "Libraries for scotch" FORCE)
#===============================================================================
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 "")
endif()
find_package_handle_standard_args(Scotch
REQUIRED_VARS SCOTCH_LIBRARIES SCOTCH_INCLUDE_DIR
VERSION_VAR SCOTCH_VERSION)
else()
find_package_handle_standard_args(Scotch DEFAULT_MSG
SCOTCH_LIBRARIES SCOTCH_INCLUDE_DIR)
endif()
diff --git a/cmake/Modules/FindSubversion.cmake b/cmake/Modules/FindSubversion.cmake
index 39a7ca234..b7ea48d7e 100644
--- a/cmake/Modules/FindSubversion.cmake
+++ b/cmake/Modules/FindSubversion.cmake
@@ -1,89 +1,118 @@
+#===============================================================================
+# @file FindSubversion.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Sun Oct 19 2014
+#
+# @brief find_package for subversion
+#
+# @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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
find_program(Subversion_SVN_EXECUTABLE svn
DOC "subversion command line client")
mark_as_advanced(Subversion_SVN_EXECUTABLE)
if(Subversion_SVN_EXECUTABLE)
# the subversion commands should be executed with the C locale, otherwise
# the message (which are parsed) may be translated, Alex
set(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}")
set(ENV{LC_ALL} C)
execute_process(COMMAND ${Subversion_SVN_EXECUTABLE} --version
OUTPUT_VARIABLE Subversion_VERSION_SVN
OUTPUT_STRIP_TRAILING_WHITESPACE)
# restore the previous LC_ALL
set(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL})
string(REGEX REPLACE "^(.*\n)?svn, version ([.0-9]+).*"
"\\2" Subversion_VERSION_SVN "${Subversion_VERSION_SVN}")
macro(Subversion_WC_INFO dir prefix)
# the subversion commands should be executed with the C locale, otherwise
# the message (which are parsed) may be translated, Alex
set(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}")
set(ENV{LC_ALL} C)
execute_process(COMMAND ${Subversion_SVN_EXECUTABLE} info ${dir}
OUTPUT_VARIABLE ${prefix}_WC_INFO
ERROR_VARIABLE Subversion_svn_info_error
RESULT_VARIABLE Subversion_svn_info_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT ${Subversion_svn_info_result} EQUAL 0)
set(${prefix}_WC_FOUND FALSE)
if(NOT "${ARGV2}" STREQUAL "ERROR_QUIET")
message(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} info ${dir}\" failed with output:\n${Subversion_svn_info_error}")
endif(NOT "${ARGV2}" STREQUAL "ERROR_QUIET")
else(NOT ${Subversion_svn_info_result} EQUAL 0)
set(${prefix}_WC_FOUND TRUE)
string(REGEX REPLACE "^(.*\n)?URL: ([^\n]+).*"
"\\2" ${prefix}_WC_URL "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Repository Root: ([^\n]+).*"
"\\2" ${prefix}_WC_ROOT "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Revision: ([^\n]+).*"
"\\2" ${prefix}_WC_REVISION "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Last Changed Author: ([^\n]+).*"
"\\2" ${prefix}_WC_LAST_CHANGED_AUTHOR "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Last Changed Rev: ([^\n]+).*"
"\\2" ${prefix}_WC_LAST_CHANGED_REV "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Last Changed Date: ([^\n]+).*"
"\\2" ${prefix}_WC_LAST_CHANGED_DATE "${${prefix}_WC_INFO}")
endif()
# restore the previous LC_ALL
set(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL})
endmacro()
macro(Subversion_WC_LOG dir prefix)
# This macro can block if the certificate is not signed:
# svn ask you to accept the certificate and wait for your answer
# This macro requires a svn server network access (Internet most of the time)
# and can also be slow since it access the svn server
execute_process(COMMAND
${Subversion_SVN_EXECUTABLE} --non-interactive log -r BASE ${dir}
OUTPUT_VARIABLE ${prefix}_LAST_CHANGED_LOG
ERROR_VARIABLE Subversion_svn_log_error
RESULT_VARIABLE Subversion_svn_log_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT ${Subversion_svn_log_result} EQUAL 0)
message(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} log -r BASE ${dir}\" failed with output:\n${Subversion_svn_log_error}")
endif()
endmacro()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Subversion REQUIRED_VARS Subversion_SVN_EXECUTABLE
VERSION_VAR Subversion_VERSION_SVN )
# for compatibility
set(Subversion_FOUND ${SUBVERSION_FOUND})
set(Subversion_SVN_FOUND ${SUBVERSION_FOUND})
diff --git a/cmake/Modules/PCHgcc.cmake b/cmake/Modules/PCHgcc.cmake
index cc3ccf1e5..528ff6a86 100644
--- a/cmake/Modules/PCHgcc.cmake
+++ b/cmake/Modules/PCHgcc.cmake
@@ -1,84 +1,83 @@
#===============================================================================
# @file PCHgcc.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Aug 31 2011
-# @date last modification: Sun Jan 06 2013
+# @date creation: Sun Oct 19 2014
#
# @brief
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
# (ADD_PCH_RULE _header_filename _src_list)
# Version 7/26/2010 4:55pm
#
# use this macro before "add_executable"
#
# _header_filename
# header to make a .gch
#
# _src_list
# the variable name (do not use ${..}) which contains a
# a list of sources (a.cpp b.cpp c.cpp ...)
# This macro will append a header file to it, then this src_list can be used in
# "add_executable..."
#
#
# Now a .gch file should be generated and gcc should use it.
# (add -Winvalid-pch to the cpp flags to verify)
#
# make clean should delete the pch file
#
# example : ADD_PCH_RULE(headers.h myprog_SRCS)
function(ADD_PCH_RULE _header_filename _src_list)
set(_gch_filename "${CMAKE_CURRENT_BINARY_DIR}/${_header_filename}.gch")
list(APPEND ${_src_list} ${_gch_filename})
set(_args ${CMAKE_CXX_FLAGS} -D__aka_inline__=inline)
get_filename_component(_gch_filename_path ${_gch_filename} PATH)
file(MAKE_DIRECTORY ${_gch_filename_path})
# list(APPEND _args -c ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename})
list(APPEND _args -c ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename} -o ${_gch_filename} -Winvalid-pch)
get_directory_property(DIRINC INCLUDE_DIRECTORIES)
foreach (_inc ${DIRINC})
list(APPEND _args "-I" ${_inc})
endforeach(_inc ${DIRINC})
separate_arguments(_args)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_header_filename} PROPERTIES GENERATED 1)
set_source_files_properties(${_gch_filename} PROPERTIES GENERATED 1)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_header_filename}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename} ${CMAKE_CURRENT_BINARY_DIR}/${_header_filename} # ensure same directory! Required by gcc
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename}
)
add_custom_command(OUTPUT ${_gch_filename}
COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} ${_args}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename}
)
endfunction(ADD_PCH_RULE _header_filename _src_list)
diff --git a/cmake/Modules/ResolveCompilerPaths.cmake b/cmake/Modules/ResolveCompilerPaths.cmake
index 644a73864..099f9bb8a 100644
--- a/cmake/Modules/ResolveCompilerPaths.cmake
+++ b/cmake/Modules/ResolveCompilerPaths.cmake
@@ -1,105 +1,134 @@
+#===============================================================================
+# @file ResolveCompilerPaths.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Sun Oct 19 2014
+#
+# @brief
+#
+# @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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
# ResolveCompilerPaths - this module defines two macros
#
# RESOLVE_LIBRARIES (XXX_LIBRARIES LINK_LINE)
# This macro is intended to be used by FindXXX.cmake modules.
# It parses a compiler link line and resolves all libraries
# (-lfoo) using the library path contexts (-L/path) in scope.
# The result in XXX_LIBRARIES is the list of fully resolved libs.
# Example:
#
# RESOLVE_LIBRARIES (FOO_LIBRARIES "-L/A -la -L/B -lb -lc -ld")
#
# will be resolved to
#
# FOO_LIBRARIES:STRING="/A/liba.so;/B/libb.so;/A/libc.so;/usr/lib/libd.so"
#
# if the filesystem looks like
#
# /A: liba.so libc.so
# /B: liba.so libb.so
# /usr/lib: liba.so libb.so libc.so libd.so
#
# and /usr/lib is a system directory.
#
# Note: If RESOLVE_LIBRARIES() resolves a link line differently from
# the native linker, there is a bug in this macro (please report it).
#
# RESOLVE_INCLUDES (XXX_INCLUDES INCLUDE_LINE)
# This macro is intended to be used by FindXXX.cmake modules.
# It parses a compile line and resolves all includes
# (-I/path/to/include) to a list of directories. Other flags are ignored.
# Example:
#
# RESOLVE_INCLUDES (FOO_INCLUDES "-I/A -DBAR='\"irrelevant -I/string here\"' -I/B")
#
# will be resolved to
#
# FOO_INCLUDES:STRING="/A;/B"
#
# assuming both directories exist.
# Note: as currently implemented, the -I/string will be picked up mistakenly (cry, cry)
include (CorrectWindowsPaths)
macro (RESOLVE_LIBRARIES LIBS LINK_LINE)
string (REGEX MATCHALL "((-L|-l|-Wl)([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))" _all_tokens "${LINK_LINE}")
set (_libs_found)
set (_directory_list)
foreach (token ${_all_tokens})
if (token MATCHES "-L([^\" ]+|\"[^\"]+\")")
# If it's a library path, add it to the list
string (REGEX REPLACE "^-L" "" token ${token})
string (REGEX REPLACE "//" "/" token ${token})
convert_cygwin_path(token)
list (APPEND _directory_list ${token})
elseif (token MATCHES "^(-l([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))")
# It's a library, resolve the path by looking in the list and then (by default) in system directories
if (WIN32) #windows expects "libfoo", linux expects "foo"
string (REGEX REPLACE "^-l" "lib" token ${token})
else (WIN32)
string (REGEX REPLACE "^-l" "" token ${token})
endif (WIN32)
set (_root)
if (token MATCHES "^/") # We have an absolute path
#separate into a path and a library name:
string (REGEX MATCH "[^/]*\\.(a|so|dll|lib)$" libname ${token})
string (REGEX MATCH ".*[^${libname}$]" libpath ${token})
convert_cygwin_path(libpath)
set (_directory_list ${_directory_list} ${libpath})
set (token ${libname})
endif (token MATCHES "^/")
set (_lib "NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
find_library (_lib ${token} HINTS ${_directory_list} ${_root})
if (_lib)
string (REPLACE "//" "/" _lib ${_lib})
list (APPEND _libs_found ${_lib})
else (_lib)
message (STATUS "Unable to find library ${token}")
endif (_lib)
endif (token MATCHES "-L([^\" ]+|\"[^\"]+\")")
endforeach (token)
set (_lib "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE)
# only the LAST occurence of each library is required since there should be no circular dependencies
if (_libs_found)
list (REVERSE _libs_found)
list (REMOVE_DUPLICATES _libs_found)
list (REVERSE _libs_found)
endif (_libs_found)
set (${LIBS} "${_libs_found}")
endmacro (RESOLVE_LIBRARIES)
macro (RESOLVE_INCLUDES INCS COMPILE_LINE)
string (REGEX MATCHALL "-I([^\" ]+|\"[^\"]+\")" _all_tokens "${COMPILE_LINE}")
set (_incs_found)
foreach (token ${_all_tokens})
string (REGEX REPLACE "^-I" "" token ${token})
string (REGEX REPLACE "//" "/" token ${token})
convert_cygwin_path(token)
if (EXISTS ${token})
list (APPEND _incs_found ${token})
else (EXISTS ${token})
message (STATUS "Include directory ${token} does not exist")
endif (EXISTS ${token})
endforeach (token)
list (REMOVE_DUPLICATES _incs_found)
set (${INCS} "${_incs_found}")
endmacro (RESOLVE_INCLUDES)
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index aab050d43..3cc2f3699 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -1,101 +1,101 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Oct 17 2012
-# @date last modification: Thu Jul 03 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Fri Jan 30 2015
#
# @brief Build the documentation
#
-
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
find_package(Doxygen REQUIRED)
if(DOXYGEN_FOUND AND AKANTU_DOCUMENTATION_DOXYGEN)
set(DOXYGEN_WARNINGS NO)
set(DOXYGEN_QUIET YES)
if(CMAKE_VERBOSE_MAKEFILE)
set(DOXYGEN_WARNINGS YES)
set(DOXYGEN_QUIET NO)
endif(CMAKE_VERBOSE_MAKEFILE)
add_subdirectory(doxygen)
endif()
file(GLOB_RECURSE __all_files "*.*")
set(_all_files)
foreach(_file ${__all_files})
if("${_file}" MATCHES "${PROJECT_SOURCE_DIR}/doc/manual")
file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_file})
list(APPEND _all_files ${__file})
endif()
endforeach()
set(AKANTU_MANUAL_FILES)
set(_akantu_manual_not_found_files)
foreach(_pkg ${${_project}_PACKAGE_SYSTEM_PACKAGES_ON})
string(TOUPPER "${_pkg}" _pkg)
foreach(_f ${AKANTU_${_pkg}_MANUAL_FILES})
#check if some file are registered but not present
list(FIND _all_files doc/manual/${_f} _ret)
if(_ret EQUAL -1)
list(APPEND _akantu_manual_not_found_files "${_pkg}: doc/manual/${_f} ")
else()
list(APPEND AKANTU_MANUAL_FILES doc/manual/${_f})
endif()
endforeach()
endforeach()
if(_akantu_manual_not_found_files)
message("")
message("******************************************************")
message("There are files registered in packages but not present")
message("******************************************************")
foreach(_file ${_akantu_manual_not_found_files})
message(${_file})
endforeach()
message("******************************************************")
message(FATAL_ERROR "abort")
endif()
################################################################
#construct the list of files to exclude because not registered
################################################################
set(_akantu_doc_exclude_files)
foreach(_file ${_all_files})
list(FIND AKANTU_MANUAL_FILES ${_file} _ret)
if(_ret EQUAL -1)
list(APPEND _akantu_doc_exclude_files /${_file})
endif()
endforeach()
list(REMOVE_ITEM _akantu_doc_exclude_files /doc/manual/CMakeLists.txt)
set(AKANTU_DOC_EXCLUDE_FILES ${_akantu_doc_exclude_files} CACHE INTERNAL "Documentation files to excluse from Akantu Package" FORCE)
if (AKANTU_DOCUMENTATION_MANUAL)
add_subdirectory(manual)
endif()
diff --git a/doc/doxygen/CMakeLists.txt b/doc/doxygen/CMakeLists.txt
index 781ce458d..2624c15ca 100644
--- a/doc/doxygen/CMakeLists.txt
+++ b/doc/doxygen/CMakeLists.txt
@@ -1,73 +1,74 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Tue Sep 28 2010
-# @date last modification: Tue Jan 14 2014
+# @date last modification: Sun Oct 19 2014
#
# @brief configuration file for doxygen
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
set(DOXYGEN_INPUT ${CMAKE_CURRENT_BINARY_DIR}/akantu.dox)
set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/html)
set(DOXYGEN_OUTPUT ${DOXYGEN_OUTPUT_DIR}/index.html)
string(REGEX REPLACE ";" " " AKANTU_DOXYGEN_DEFINTIONS "${AKANTU_DEFINITIONS}")
string(REGEX REPLACE ";" " " AKANTU_DOXYGEN_INCLUDE_DIRS "${AKANTU_INCLUDE_DIRS}")
make_directory(${DOXYGEN_OUTPUT_DIR})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/akantu.dox.in
${CMAKE_CURRENT_BINARY_DIR}/akantu.dox)
add_custom_command(
OUTPUT ${DOXYGEN_OUTPUT} #${CMAKE_CURRENT_BINARY_DIR}/latex/refman.tex
COMMAND ${CMAKE_COMMAND} -E echo "${DOXYGEN_EXECUTABLE} ${DOXYGEN_INPUT}"
COMMAND ${CMAKE_COMMAND} -E echo_append "Building akantu Documentation..."
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_INPUT}
COMMAND ${CMAKE_COMMAND} -E echo "Done."
DEPENDS ${DOXYGEN_INPUT}
)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/latex/refman.pdf
COMMAND ${CMAKE_COMMAND} -E echo "Building akantu RefMan..."
COMMAND make -C ${CMAKE_CURRENT_BINARY_DIR}/latex
#COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/latex/refman.pdf ${CMAKE_CURRENT_BINARY_DIR}/refman.pdf
COMMAND ${CMAKE_COMMAND} -E echo "Done."
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/latex/refman.tex
)
#add_custom_target(akantu-doc-pdf ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/latex/refman.pdf)
add_custom_target(akantu-doc ALL DEPENDS ${DOXYGEN_OUTPUT})
add_custom_target(akantu-doc-forced
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_INPUT}
)
install(DIRECTORY ${DOXYGEN_OUTPUT_DIR}
DESTINATION share/akantu-${AKANTU_VERSION}/doc)
diff --git a/doc/manual/CMakeLists.txt b/doc/manual/CMakeLists.txt
index 5348490e2..0d40dc36b 100644
--- a/doc/manual/CMakeLists.txt
+++ b/doc/manual/CMakeLists.txt
@@ -1,155 +1,156 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Jun 09 2014
-# @date last modification: Thu Jul 03 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Wed Jan 06 2016
#
# @brief Build the documentation
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
#------------------------------------------------------------------------------#
function(get_doc_label pkg_name label)
string(REPLACE "_" "-" _pkg_tex_label_dash ${pkg_name})
string(TOLOWER "${_pkg_tex_label_dash}" _pkg_tex_label)
set(TOLOWER "${_pkg_tex_label_dash}" _pkg_tex_label)
set(${label} "pkg:${_pkg_tex_label}" PARENT_SCOPE)
endfunction()
function(get_doc_package_name pkg_name pkg_tex)
_package_get_option_name(${pkg_name} _opt_name)
string(REPLACE "_" "\\_" _pkg_tex "${_opt_name}")
set(${pkg_tex} ${_pkg_tex} PARENT_SCOPE)
endfunction()
#------------------------------------------------------------------------------#
function(generate_package_dependency_tex_doc pkg_name FILENAME LEVEL)
_package_get_option_name(${pkg_name} _opt_name)
string(REPLACE "_" "\\_" _pkg_tex "${_opt_name}")
get_doc_label(${pkg_name} _pkg_tex_label)
file(APPEND ${FILENAME} "\\AkantuPackageNameWithLabel{${_pkg_tex}}{${_pkg_tex_label}}{${LEVEL}}\\xspace")
math(EXPR _sub_level "${LEVEL}+1")
_package_get_dependencies(${pkg_name} _dependencies)
foreach(_dep_pkg_name ${_dependencies})
generate_package_dependency_tex_doc(${_dep_pkg_name} ${FILENAME} ${_sub_level})
endforeach()
endfunction()
#------------------------------------------------------------------------------#
function(generate_package_tex_doc pkg_name FILENAME)
get_doc_package_name(${pkg_name} _pkg_tex)
get_doc_label(${pkg_name} _pkg_tex_label)
file(APPEND ${FILENAME} "\n\\begin{AkantuPackage}{${_pkg_tex}}{${_pkg_tex_label}}")
_package_get_documentation(${pkg_name} _doc)
if (_doc)
file(APPEND ${FILENAME} "${_doc}")
else()
_package_get_filename(${pkg_name} _file_path)
_package_get_real_name(${pkg_name} _pkg)
get_filename_component(_file ${_file_path} NAME)
string(REPLACE "_" "\\_" _escaped_file "${_file}")
string(REPLACE "_" "\\_" _escaped_pkg "${_pkg}")
set(_missing_doc
"{\\color{red} TODO}: No Documentation in {\\color{blue} \\href{${_file_path}}{${_escaped_file}}}"
""
"looking for the sequence: "
"\\begin{cmake}"
"\\package_declare_documentation("
" ${_escaped_pkg}"
" \"documentation text\""
" )"
"\\end{cmake}")
set(_missing_doc_str "")
foreach(_str ${_missing_doc})
set(_missing_doc_str "${_missing_doc_str}\n${_str}")
endforeach()
file(APPEND ${FILENAME} "${_missing_doc_str}")
endif()
_package_get_dependencies(${pkg_name} _dependencies)
if(_dependencies)
file(APPEND ${FILENAME} "\n\\begin{AkantuPackageDependencies}")
foreach(_dep_pkg_name ${_dependencies})
generate_package_dependency_tex_doc(${_dep_pkg_name} ${FILENAME} 1)
endforeach()
file(APPEND ${FILENAME} "\n\\end{AkantuPackageDependencies}")
endif()
file(APPEND ${FILENAME} "\n\\end{AkantuPackage}
")
endfunction()
#------------------------------------------------------------------------------#
#------------------------------------------------------------------------------#
set(DOC_DEPS_TEX_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/manual-packages-doc.tex")
file(WRITE ${DOC_DEPS_TEX_FILENAME} "")
find_program(RUBBER_EXECUTABLE rubber)
if (NOT RUBBER_EXECUTABLE)
message(ERROR "Manual cannot be built without rubber latex compiler")
endif()
mark_as_advanced(RUBBER_EXECUTABLE)
package_get_all_documentation_files(_manual_files)
set(AKANTU_MANUAL_FILES_DEPEND)
set(AKANTU_MANUAL_FILES_COPY_COMMAND)
foreach(_f ${_manual_files})
file(RELATIVE_PATH _rel_f ${CMAKE_CURRENT_SOURCE_DIR} "${_f}")
list(APPEND AKANTU_MANUAL_FILES_DEPEND ${_f})
list(APPEND AKANTU_MANUAL_FILES_COPY_COMMAND
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${_rel_f} ${_rel_f})
endforeach()
set(MANUAL_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/manual.pdf)
add_custom_command(
OUTPUT ${MANUAL_OUTPUT}
DEPENDS ${AKANTU_MANUAL_FILES_DEPEND} ${DOC_DEPS_TEX_FILENAME}
${AKANTU_MANUAL_FILES_COPY_COMMAND}
COMMAND ${RUBBER_EXECUTABLE} -dfq -Wall manual
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Compiling the user's manual"
)
add_custom_target(manual ALL DEPENDS ${MANUAL_OUTPUT})
install(FILES ${MANUAL_OUTPUT} DESTINATION share/akantu/doc)
package_get_all_activated_packages(_package_list)
foreach (_pkg_name ${_package_list})
generate_package_tex_doc(${_pkg_name} ${DOC_DEPS_TEX_FILENAME})
endforeach()
configure_file(version-definition.tex.in "${CMAKE_CURRENT_BINARY_DIR}/version-definition.tex" @ONLY)
\ No newline at end of file
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index b6a1e7ac7..04d6b0d09 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,53 +1,54 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Fri Feb 24 2012
-# @date last modification: Tue Sep 23 2014
+# @date creation: Fri Oct 22 2010
+# @date last modification: Mon Dec 14 2015
#
# @brief List of examples
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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}
)
#===============================================================================
add_example(new_material "Example on how to add a new material in Akantu" PACKAGE core)
add_example(boundary_conditions "Example on hoy to set boundary conditions" PACKAGE core)
add_example(explicit "Example on how to run an explicit simulation" PACKAGE core)
add_example(io "Example on how to perform Input/Output operations" PACKAGE core)
add_example(implicit "Example on how to run an implicit simulation" PACKAGE implicit)
add_example(static "Example on how to run a static simulation" PACKAGE implicit)
add_example(parallel_2d "Example of how to write a parallel code with Akantu" PACKAGE parallel)
add_example(cohesive_element "Cohesive element examples" PACKAGE cohesive_element)
add_example(contact "Examples on how to use contact within Akantu" PACKAGE contact)
add_example(optimization "Optimization examples" PACKAGE optimization)
add_example(structural_mechanics "Structural mechanics model examples" PACKAGE structural_mechanics)
add_example(heat_transfer "Example on how to run heat transfer simulation" PACKAGE heat_transfer)
add_example(embedded "Example on how to run embedded model simulation" PACKAGE embedded)
#===============================================================================
diff --git a/examples/boundary_conditions/CMakeLists.txt b/examples/boundary_conditions/CMakeLists.txt
index 2914073ce..d169d67ee 100644
--- a/examples/boundary_conditions/CMakeLists.txt
+++ b/examples/boundary_conditions/CMakeLists.txt
@@ -1,32 +1,31 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
#
-# @date creation: Fri Jun 21 2013
-# @date last modification: Fri Jun 21 2013
+# @date creation: Wed Dec 16 2015
#
# @brief CMakeLists for the cohesive examples
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
add_example(predefined_BC "Example of predefined boundary condition")
add_example(user_defined_BC "Example of user defined boundary condition" PACKAGE implicit)
\ No newline at end of file
diff --git a/examples/boundary_conditions/predefined_BC/CMakeLists.txt b/examples/boundary_conditions/predefined_BC/CMakeLists.txt
index aa209f7a6..bbb9ea05b 100644
--- a/examples/boundary_conditions/predefined_BC/CMakeLists.txt
+++ b/examples/boundary_conditions/predefined_BC/CMakeLists.txt
@@ -1,39 +1,38 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
#
-# @date creation: Fri May 11 2012
-# @date last modification: Thu Nov 01 2012
+# @date creation: Wed Dec 16 2015
#
# @brief boundary condition example configuration
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
add_mesh(plate_mesh square.geo 2 1)
register_example(plate plate.cc)
add_dependencies(plate plate_mesh)
file(COPY material.dat DESTINATION .)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
\ No newline at end of file
diff --git a/examples/boundary_conditions/predefined_BC/plate.cc b/examples/boundary_conditions/predefined_BC/plate.cc
index 9211fc1d4..cdd7e11bb 100644
--- a/examples/boundary_conditions/predefined_BC/plate.cc
+++ b/examples/boundary_conditions/predefined_BC/plate.cc
@@ -1,97 +1,96 @@
/**
* @file plate.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri May 11 2012
- * @date last modification: Mon Apr 07 2014
+ * @date creation: Wed Dec 16 2015
*
* @brief boundary condition example
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
//Do I need to define the element type?
UInt spatial_dimension = 2;
UInt max_steps = 3000;
Mesh mesh(spatial_dimension);
mesh.read("square.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.assembleMassLumped();
/// Dirichlet boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y");
model.updateResidual();
model.setBaseName("plate");
model.addDumpFieldVector("displacement");
model.addDumpField("blocked_dofs");
model.addDumpField("force" );
model.addDumpField("residual" );
model.dump();
Real time_step = model.getStableTimeStep() * .8;
model.setTimeStep(time_step);
Vector<Real> traction(2);
for(UInt s = 1; s <= max_steps; ++s) {
if(s % 100 == 0)
std::cout << "passing step " << s << "/" << max_steps << std::endl;
// Neumann boundary condition
traction(0) = s*0.1;
traction(1) = 0.0;
model.applyBC(BC::Neumann::FromTraction(traction), "Traction");
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
if(s % 10 == 0)
model.dump();
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/boundary_conditions/user_defined_BC/CMakeLists.txt b/examples/boundary_conditions/user_defined_BC/CMakeLists.txt
index 3bb958d10..6b44e511f 100644
--- a/examples/boundary_conditions/user_defined_BC/CMakeLists.txt
+++ b/examples/boundary_conditions/user_defined_BC/CMakeLists.txt
@@ -1,39 +1,38 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
#
-# @date creation: Fri May 11 2012
-# @date last modification: Thu Nov 01 2012
+# @date creation: Wed Dec 16 2015
#
# @brief boundary condition example configuration
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
add_mesh(mesh fine_mesh.geo 2 1)
register_example(complex_boundary_condition complex_boundary_condition.cc)
add_dependencies(complex_boundary_condition mesh)
file(COPY material.dat DESTINATION .)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
\ No newline at end of file
diff --git a/examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc b/examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc
index f31c4e3c3..50b8ac4cb 100644
--- a/examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc
+++ b/examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc
@@ -1,97 +1,97 @@
/**
* @file complex_boundary_condition.cc
*
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Wed Dec 16 2015
*
* @brief user-defined boundary condition example
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <math.h>
/* -------------------------------------------------------------------------- */
using namespace akantu;
class SineBoundary : public BC::Dirichlet::DirichletFunctor {
public:
SineBoundary(Real amp, Real phase, BC::Axis ax = _x) : DirichletFunctor(ax), amplitude(amp), phase(phase) {}
public:
inline void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = true;
primal(axis) = -amplitude * sin(phase * coord(1));
}
protected:
Real amplitude;
Real phase;
};
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("fine_mesh.msh");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelOptions(_static));
std::cout << model.getMaterial(0) << std::endl;
model.assembleMassLumped();
/// boundary conditions
mesh.createGroupsFromMeshData<std::string>("physical_names");
Vector<Real> traction(2, 0.2);
model.applyBC(SineBoundary(.2, 10., _x), "Fixed_x");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Fixed_y");
model.applyBC(BC::Neumann::FromTraction(traction), "Traction");
model.setBaseName("plate");
model.addDumpFieldVector("displacement");
model.addDumpField("blocked_dofs");
model.dump();
/// solve the system
model.assembleStiffnessMatrix();
Real error = 0;
Real converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-10, error, 2, false);
AKANTU_DEBUG_ASSERT(converged, "Did not converge");
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/cohesive_element/CMakeLists.txt b/examples/cohesive_element/CMakeLists.txt
index feff3d67f..1f871bf2a 100644
--- a/examples/cohesive_element/CMakeLists.txt
+++ b/examples/cohesive_element/CMakeLists.txt
@@ -1,34 +1,33 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
#
-# @date creation: Fri Jun 21 2013
-# @date last modification: Tue Jan 07 2016
+# @date creation: Tue Jan 12 2016
#
# @brief CMakeLists for the cohesive examples
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
add_example(cohesive_extrinsic "Extrinsic cohesive element" PACKAGE cohesive_element)
add_example(cohesive_intrinsic "Intrinsic cohesive element" PACKAGE cohesive_element )
add_example(cohesive_extrinsic_IG_TG "Extrinsic cohesive element with intergranular and transgranular material properties" PACKAGE cohesive_element)
add_example(cohesive_extrinsic_implicit "Extrinsic cohesive element in implicit" PACKAGE cohesive_element )
\ No newline at end of file
diff --git a/examples/cohesive_element/cohesive_extrinsic/CMakeLists.txt b/examples/cohesive_element/cohesive_extrinsic/CMakeLists.txt
index 163fd45a9..729a1ab8d 100644
--- a/examples/cohesive_element/cohesive_extrinsic/CMakeLists.txt
+++ b/examples/cohesive_element/cohesive_extrinsic/CMakeLists.txt
@@ -1,40 +1,39 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
#
-# @date creation: Fri Jun 21 2013
-# @date last modification: Mon Apr 07 2014
+# @date creation: Sun Oct 19 2014
#
# @brief configuration for extrinsic cohesive elements
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
register_example(cohesive_extrinsic cohesive_extrinsic.cc)
add_mesh(cohesive_extrinsic_mesh triangle.geo 2 2)
add_dependencies(cohesive_extrinsic cohesive_extrinsic_mesh)
#===============================================================================
file(COPY material.dat DESTINATION .)
diff --git a/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc b/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc
index c7dc095b8..755dfec80 100644
--- a/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc
+++ b/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc
@@ -1,141 +1,140 @@
/**
* @file cohesive_extrinsic.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri Jun 21 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 2;
const UInt max_steps = 1000;
Mesh mesh(spatial_dimension);
mesh.read("triangle.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
Real time_step = model.getStableTimeStep()*0.05;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
CohesiveElementInserter & inserter = model.getElementInserter();
inserter.setLimit(_y, 0.30, 0.20);
model.updateAutomaticInsertion();
Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
boundary(n, 1) = true;
if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
boundary(n, 0) = true;
}
model.updateResidual();
model.setBaseName("extrinsic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("residual" );
model.addDumpField("stress");
model.addDumpField("grad_u");
model.dump();
/// initial conditions
Real loading_rate = 0.5;
Real disp_update = loading_rate * time_step;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 1) = loading_rate * position(n, 1);
}
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
/// update displacement on extreme nodes
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
displacement(n, 1) += disp_update * position(n, 1);
}
model.checkCohesiveStress();
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
if(s % 10 == 0) {
model.dump();
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
}
Real Ed = model.getEnergy("dissipated");
Real Edt = 200*std::sqrt(2);
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_extrinsic was passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/examples/cohesive_element/cohesive_extrinsic_IG_TG/CMakeLists.txt b/examples/cohesive_element/cohesive_extrinsic_IG_TG/CMakeLists.txt
index 3028fbb46..5281ddf21 100644
--- a/examples/cohesive_element/cohesive_extrinsic_IG_TG/CMakeLists.txt
+++ b/examples/cohesive_element/cohesive_extrinsic_IG_TG/CMakeLists.txt
@@ -1,41 +1,40 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
#
-# @date creation: Fri Jun 21 2013
-# @date last modification: Fri Jun 21 2013
+# @date creation: Sun Oct 19 2014
#
# @brief Configuration for cohesive_extrinsic_IG_TG
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
register_example(cohesive_extrinsic_IG_TG
cohesive_extrinsic_IG_TG.cc)
#===============================================================================
file(COPY material.dat DESTINATION .)
file(COPY square.msh DESTINATION .)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
diff --git a/examples/cohesive_element/cohesive_extrinsic_IG_TG/cohesive_extrinsic_IG_TG.cc b/examples/cohesive_element/cohesive_extrinsic_IG_TG/cohesive_extrinsic_IG_TG.cc
index ded0af86b..19e2dc484 100644
--- a/examples/cohesive_element/cohesive_extrinsic_IG_TG/cohesive_extrinsic_IG_TG.cc
+++ b/examples/cohesive_element/cohesive_extrinsic_IG_TG/cohesive_extrinsic_IG_TG.cc
@@ -1,212 +1,211 @@
/**
* @file cohesive_extrinsic_IG_TG.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri Jun 21 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief Test for considering different cohesive properties for intergranular (IG) and
* transgranular (TG) fractures in extrinsic cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
class MultiGrainMaterialSelector : public DefaultMaterialCohesiveSelector {
public:
MultiGrainMaterialSelector(const SolidMechanicsModelCohesive & model, const ID & transgranular_id, const ID & intergranular_id) :
DefaultMaterialCohesiveSelector(model),
transgranular_id(transgranular_id),
intergranular_id(intergranular_id),
model(model),
mesh(model.getMesh()),
mesh_facets(model.getMeshFacets()),
spatial_dimension(model.getSpatialDimension()),
nb_IG(0), nb_TG(0) {
}
UInt operator()(const Element & element) {
if(mesh_facets.getSpatialDimension(element.type) == (spatial_dimension - 1)) {
const std::vector<Element> & element_to_subelement = mesh_facets.getElementToSubelement(element.type, element.ghost_type)(element.element);
const Element & el1 = element_to_subelement[0];
const Element & el2 = element_to_subelement[1];
UInt grain_id1 = mesh.getData<UInt>("tag_0", el1.type, el1.ghost_type)(el1.element);
if(el2 != ElementNull) {
UInt grain_id2 = mesh.getData<UInt>("tag_0", el2.type, el2.ghost_type)(el2.element);
if (grain_id1 == grain_id2){
//transgranular = 0 indicator
nb_TG++;
return model.getMaterialIndex(transgranular_id);
} else {
//intergranular = 1 indicator
nb_IG++;
return model.getMaterialIndex(intergranular_id);
}
} else {
//transgranular = 0 indicator
nb_TG++;
return model.getMaterialIndex(transgranular_id);
}
} else {
return DefaultMaterialCohesiveSelector::operator()(element);
}
}
private:
ID transgranular_id, intergranular_id;
const SolidMechanicsModelCohesive & model;
const Mesh & mesh;
const Mesh & mesh_facets;
UInt spatial_dimension;
UInt nb_IG;
UInt nb_TG;
};
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 2;
const UInt max_steps = 1000;
Mesh mesh(spatial_dimension);
mesh.read("square.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
MultiGrainMaterialSelector material_selector(model, "TG_cohesive", "IG_cohesive");
model.setMaterialSelector(material_selector);
model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true, false));
Real time_step = model.getStableTimeStep()*0.05;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99|| position(n, 1) < -0.99)
boundary(n, 1) = true;
if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
boundary(n, 0) = true;
}
model.updateResidual();
model.setBaseName("extrinsic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("residual" );
model.addDumpField("stress");
model.addDumpField("grad_u");
model.dump();
/// initial conditions
Real loading_rate = 0.1;
// bar_height = 2
Real VI = loading_rate * 2* 0.5;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 1) = loading_rate * position(n, 1);
velocity(n, 0) = loading_rate * position(n, 0);
}
model.dump();
Real dispy = 0;
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
dispy += VI * time_step;
/// update displacement on extreme nodes
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (position(n, 1) > 0.99){
displacement(n, 1) = dispy;
velocity(n,1) = VI;}
if (position(n, 1) < -0.99){
displacement(n, 1) = -dispy;
velocity(n,1) = -VI;}
if (position(n, 0) > 0.99){
displacement(n, 0) = dispy;
velocity(n,0) = VI;}
if (position(n, 0) < -0.99){
displacement(n, 0) = -dispy;
velocity(n,0) = -VI;}
}
model.checkCohesiveStress();
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
model.dump();
if(s % 10 == 0) {
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
}
Real Ed = model.getEnergy("dissipated");
Real Edt = 40;
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
finalize();
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_extrinsic_IG_TG was passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt b/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt
index 82e96a5f2..f331aab09 100644
--- a/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt
+++ b/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt
@@ -1,42 +1,42 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Mauro Corrado <mauro.corrado@epfl.ch>
#
-# @date creation: Tue Jan 07 2016
+# @date creation: Tue Jan 12 2016
#
# @brief Example for extrinsic cohesive elements in implicit
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
add_mesh(cohesive_extrinsic_implicit_mesh dcb_2d.geo 2 2)
register_example(cohesive_extrinsic_implicit
cohesive_extrinsic_implicit.cc)
add_dependencies(cohesive_extrinsic_implicit
cohesive_extrinsic_implicit_mesh)
#===============================================================================
file(COPY material.dat DESTINATION .)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
diff --git a/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc b/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc
index 7b7eae030..77bbb9b01 100644
--- a/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc
+++ b/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc
@@ -1,171 +1,170 @@
/**
* @file cohesive_extrinsic_implicit.cc
*
- * @author Mauro Corrado
*
- * @date creation: Tue Jan 07 2016
+ * @date creation: Tue Jan 12 2016
*
* @brief Example for extrinsic cohesive elements in implicit
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblError);
const UInt spatial_dimension = 2;
const UInt max_steps = 20;
const Real final_opening = 1e-4;
Mesh mesh(spatial_dimension);
mesh.read("dcb_2d.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelCohesiveOptions(_static, true));
// CohesiveElementInserter inserter(mesh);
model.limitInsertion(_y, -0.000001, 0.000001);
model.updateAutomaticInsertion();
Real eps = 1e-11;
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & position = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
/// boundary conditions
mesh.computeBoundingBox();
const Vector<Real> & lower = mesh.getLowerBounds();
const Vector<Real> & upper = mesh.getUpperBounds();
const Real left = lower[0];
const Real right = upper[0];
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (std::abs(position(n,0) - left) < eps){
boundary(n,1) = true;
boundary(n,0) = true;
}
if (std::abs(position(n,0) - right) < eps && position(n,1) < 0.0)
boundary(n,1) = true;
if (std::abs(position(n,0) - right) < eps && position(n,1) > 0.0)
boundary(n,1) = true;
}
model.setBaseName("extr_impl");
model.addDumpFieldVector("displacement");
model.addDumpField("force");
model.addDumpField("residual");
model.addDumpField("stress");
model.addDumpField("partitions");
model.dump();
// Dumping cohesive elements
model.setBaseNameToDumper("cohesive elements", "cohe_elem_extr_impl");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump("cohesive elements");
// model.updateResidual();
Real increment = final_opening/max_steps;
Real tolerance = 1e-13;
Real error;
bool load_reduction = false;
Real tol_increase_factor = 1.0e8;
/// Main loop
for (UInt nstep = 0; nstep < max_steps; ++nstep){
std::cout << "step no. " << nstep << std::endl;
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (std::abs(position(n,0) - right) < eps && position(n,1) > 0.0)
displacement(n,1) += increment;
if (std::abs(position(n,0) - right) < eps && position(n,1) < 0.0)
displacement(n,1) -= increment;
}
model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
// If convergence has not been reached, the load is reduced and
// the incremental step is solved again.
while (!load_reduction && error > tolerance) {
load_reduction = true;
std::cout << "LOAD STEP REDUCTION" << std::endl;
increment = increment / 2.0;
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (std::abs(position(n,0) - right) < eps && position(n,1) > 0.0)
displacement(n,1) -= increment;
if (std::abs(position(n,0) - right) < eps && position(n,1) < 0.0)
displacement(n,1) += increment;
}
UInt nb_cohesive_elements = mesh.getNbElement(spatial_dimension, _not_ghost, _ek_cohesive);
model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
UInt new_nb_cohesive_elements = mesh.getNbElement(spatial_dimension, _not_ghost, _ek_cohesive);
UInt nb_cohe[2];
nb_cohe[0] = nb_cohesive_elements;
nb_cohe[1] = new_nb_cohesive_elements;
// Every time a new cohesive element is introduced, the variable
// load_reduction is set to false, so that it is possible to
// further iterate in the loop of load reduction. If no new
// cohesive elements are introduced, usually there is no gain in
// further reducing the load, even if convergence is not reached
if(nb_cohe[0] == nb_cohe[1])
load_reduction = true;
else
load_reduction = false;
}
model.dump();
model.dump("cohesive elements");
UInt nb_cohe_elems[1];
nb_cohe_elems[0] = mesh.getNbElement(spatial_dimension, _not_ghost, _ek_cohesive);
std::cout << "No. of cohesive elements: " << nb_cohe_elems[0] << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/cohesive_element/cohesive_intrinsic/CMakeLists.txt b/examples/cohesive_element/cohesive_intrinsic/CMakeLists.txt
index 312c8707b..9a3db78b0 100644
--- a/examples/cohesive_element/cohesive_intrinsic/CMakeLists.txt
+++ b/examples/cohesive_element/cohesive_intrinsic/CMakeLists.txt
@@ -1,45 +1,44 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
#
-# @date creation: Fri Jun 21 2013
-# @date last modification: Fri Jun 21 2013
+# @date creation: Sun Oct 19 2014
#
# @brief Intrinsic cohesive element configuration
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
add_mesh( cohesive_intrinsic_mesh triangle.geo 2 2)
register_example(cohesive_intrinsic
cohesive_intrinsic.cc)
add_dependencies(cohesive_intrinsic
cohesive_intrinsic_mesh)
#===============================================================================
file(COPY material.dat DESTINATION .)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
diff --git a/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc b/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc
index 6d8916bd0..89eb1e546 100644
--- a/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc
+++ b/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc
@@ -1,174 +1,173 @@
/**
* @file cohesive_intrinsic.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri Jun 21 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "mesh_utils.hh"
#include "solid_mechanics_model_cohesive.hh"
#include "material.hh"
//#include "io_helper.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
static void updateDisplacement(SolidMechanicsModelCohesive &,
Array<UInt> &,
ElementType,
Real);
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
// debug::setDebugLevel(dblDump);
const UInt spatial_dimension = 2;
const UInt max_steps = 350;
const ElementType type = _triangle_6;
Mesh mesh(spatial_dimension);
mesh.read("triangle.msh");
CohesiveElementInserter inserter(mesh);
inserter.setLimit(_x, -0.26, -0.24);
inserter.insertIntrinsicElements();
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull();
Real time_step = model.getStableTimeStep()*0.8;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
Array<bool> & boundary = model.getBlockedDOFs();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_element = mesh.getNbElement(type);
/// boundary conditions
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
for (UInt n = 0; n < nb_nodes; ++n) {
boundary(n, dim) = true;
}
}
model.updateResidual();
model.setBaseName("intrinsic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("residual" );
model.addDumpField("stress");
model.addDumpField("grad_u");
model.addDumpField("force");
model.dump();
/// update displacement
Array<UInt> elements;
Real * bary = new Real[spatial_dimension];
for (UInt el = 0; el < nb_element; ++el) {
mesh.getBarycenter(el, type, bary);
if (bary[0] > -0.25) elements.push_back(el);
}
delete[] bary;
Real increment = 0.01;
updateDisplacement(model, elements, type, increment);
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
model.solveStep();
updateDisplacement(model, elements, type, increment);
if(s % 1 == 0) {
model.dump();
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
}
Real Ed = model.getEnergy("dissipated");
Real Edt = 2 * sqrt(2);
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_intrinsic was passed!" << std::endl;
return EXIT_SUCCESS;
}
static void updateDisplacement(SolidMechanicsModelCohesive & model,
Array<UInt> & elements,
ElementType type,
Real increment) {
Mesh & mesh = model.getMesh();
UInt nb_element = elements.getSize();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Array<Real> & displacement = model.getDisplacement();
Array<bool> update(nb_nodes);
update.clear();
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity(elements(el), n);
if (!update(node)) {
displacement(node, 0) -= increment;
// displacement(node, 1) += increment;
update(node) = true;
}
}
}
}
diff --git a/examples/contact/CMakeLists.txt b/examples/contact/CMakeLists.txt
index 67168b8ad..699d2ec1e 100644
--- a/examples/contact/CMakeLists.txt
+++ b/examples/contact/CMakeLists.txt
@@ -1,57 +1,57 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
#
-# @date Mon Mar 24 11:30:00 2014
+# @date creation: Sun Oct 19 2014
#
# @brief configuration file for contact examples
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
register_example(hertz_2D hertz_2D.cc)
add_mesh(hertz_2D_mesh hertz_2D.geo 2 1)
add_dependencies(hertz_2D hertz_2D_mesh)
register_example(hertz_3D hertz_3D.cc)
add_mesh(hertz_3D_mesh hertz_3D.geo 3 1)
add_dependencies(hertz_3D hertz_3D_mesh)
register_example(tetrahedra tetrahedra.cc)
add_mesh(tetrahedra_mesh tetrahedra.geo 3 1)
add_dependencies(tetrahedra tetrahedra_mesh)
register_example(blocks blocks.cc)
add_mesh(blocks_mesh blocks.geo 2 1)
add_dependencies(blocks blocks_mesh)
#===============================================================================
file(COPY steel.dat DESTINATION .)
\ No newline at end of file
diff --git a/examples/contact/blocks.cc b/examples/contact/blocks.cc
index 33776efc4..de9a56829 100644
--- a/examples/contact/blocks.cc
+++ b/examples/contact/blocks.cc
@@ -1,136 +1,135 @@
/**
* @file blocks.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date Tue Jan 14 09:38:00 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief Example of two blocks in contact
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
-
#include <iostream>
#include <chrono>
#include "contact_impl.hh"
using namespace akantu;
using std::cout;
using std::endl;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 2;
typedef std::chrono::high_resolution_clock clock;
typedef std::chrono::seconds seconds;
typedef SolidMechanicsModel model_type;
typedef Contact <dim, MasterAssignator, SelectResolution <_static, _augmented_lagrangian> >
contact_type;
// capture initial time
clock::time_point t0 = clock::now();
initialize("steel.dat", argc, argv);
// create and read mesh
Mesh mesh(dim);
mesh.read("blocks.msh");
// create model
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
// initialize material
model.initFull(opt);
// setup paraview dumper
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// get areas for slave nodes
mesh.createGroupsFromMeshData<std::string>("physical_names");
model.applyBC(BC::Neumann::FromHigherDim(Matrix<Real>::eye(2,1.)), "interface_top");
Array<Real>& areas = model.getForce();
ElementGroup &eg = mesh.getElementGroup("interface_top");
for (auto nit = eg.node_begin(); nit != eg.node_end(); ++nit) {
// add slave node
cd.addSlave(*nit);
// compute and add area
Real a = 0.;
for (UInt i=0; i<dim; ++i)
a += pow(areas(*nit, i),2.);
cd.addArea(*nit, sqrt(a));
}
// set force value to zero
areas.clear();
// add master surface to find pairs
cd.searchSurface("interface_bottom");
// apply boundary conditions
using BC::Dirichlet::FixedValue;
model.applyBC(FixedValue(0., _x), "bottom");
model.applyBC(FixedValue(0., _y), "bottom");
model.applyBC(FixedValue(0., _x), "top");
Real U = 0.5;
Real Du = 0.005;
// loop over command line parameters
for (int i=0; i<argc; ++i) {
if (strcmp(argv[i], "-steps") == 0) {
Real steps = atof(argv[++i]);
cout<<"-steps = "<<steps<<endl;
Du = U / steps;
}
}
// loop over load increments
for (Real u = Du; u<=U; u += Du) {
model.applyBC(FixedValue(-u, _y), "top");
solveContactStep<_generalized_newton>(cd);
}
clock::time_point t1 = clock::now();
seconds total_s = std::chrono::duration_cast<seconds>(t1 - t0);
cout<<"- Simulation took "<<total_s.count()<<" s"<<endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/contact/hertz_2D.cc b/examples/contact/hertz_2D.cc
index 6294abbd4..05f93b05f 100644
--- a/examples/contact/hertz_2D.cc
+++ b/examples/contact/hertz_2D.cc
@@ -1,166 +1,166 @@
/**
* @file hertz_2D.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date Tue Jan 14 09:38:00 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief File used to obtain 2D implicit contact results and compare with
* Hertz theory
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <chrono>
#include "contact_impl.hh"
using namespace akantu;
using std::cout;
using std::endl;
using std::setw;
using std::setprecision;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 2;
typedef Point <dim> point_type;
typedef BoundingBox <dim> bbox_type;
typedef SolidMechanicsModel model_type;
typedef Contact <dim, MasterAssignator, SelectResolution <_static, _augmented_lagrangian> >
contact_type;
typedef std::chrono::high_resolution_clock clock;
typedef std::chrono::seconds seconds;
clock::time_point t0 = clock::now();
initialize("steel.dat", argc, argv);
// create mesh
Mesh mesh(dim);
// read mesh
mesh.read("hertz_2D.msh");
// create model
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// optimal value of penalty multiplier
cd[Alpha] = 1.e-6;
cd[Verbose] = true;
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
// use bounding box to minimize slave-master pairs
Real r0 = 0.5;
Real r1 = 0.15;
point_type c1(-r0 / 2, -r1 / 2);
point_type c2(r0 / 2, r1 / 2);
bbox_type bb(c1, c2);
// get physical names from mesh
Array <Real> &coords = mesh.getNodes();
mesh.createGroupsFromMeshData <std::string>("physical_names");
// compute areas for slave nodes that are used for the computation of contact pressures
model.applyBC(BC::Neumann::FromHigherDim(Matrix <Real>::eye(2, 1.)), "contact_surface");
// NOTE: the areas are computed by assigning a unit pressure to the contact surface,
// then the magnitude of the resulting force vector at nodes gives its associated area
Array <Real>& areas = model.getForce();
// add slave-master pairs and store slave node areas
ElementGroup &eg = mesh.getElementGroup("contact_surface");
for (auto nit = eg.node_begin(); nit != eg.node_end(); ++nit) {
// get point of slave node
point_type n(&coords(*nit));
// process only if within bounding box
if (bb & n) {
cd.addSlave(*nit);
// compute and add area to slave node
Real a = 0.;
for (UInt i = 0; i < dim; ++i)
a += pow(areas(*nit, i), 2.);
cd.addArea(*nit, sqrt(a));
}
}
// clear force vector before the start of the simulation
areas.clear();
// add master surface to find pairs
cd.searchSurface("rigid");
// output contact data info
cout << cd;
// apply boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "rigid");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "rigid");
model.getBlockedDOFs()(7, 0) = true;
Real data[3][50]; // store results for printing
Real step = 0.001; // top displacement increment
Real Delta = 0.05; // maximum imposed displacement
size_t k = 0;
// loop over displacement increments
for (Real delta = step; delta <= Delta + step; delta += step) {
// apply displacement at the top
model.applyBC(BC::Dirichlet::FixedValue(-delta, _y), "top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_generalized_newton>(cd);
data[0][k] = delta;
data[1][k] = cd.getForce();
data[2][k] = cd.getMaxPressure();
++k;
}
// print results
size_t w = 10;
cout << setprecision(2);
cout << "\n\n" << setw(w) << "Disp." << setw(w) << "Force" << setw(w) << "Max pressure" << endl;
for (int i = 0; i < 50; ++i)
cout << setw(w) << data[0][i] << setw(w) << data[1][i] << setw(w) << data[2][i] << endl;
clock::time_point t1 = clock::now();
seconds total_s = std::chrono::duration_cast <seconds>(t1 - t0);
cout << "*** INFO *** Simulation took " << total_s.count() << " s" << endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/contact/hertz_3D.cc b/examples/contact/hertz_3D.cc
index 9e0ff5c9c..e71566fd5 100644
--- a/examples/contact/hertz_3D.cc
+++ b/examples/contact/hertz_3D.cc
@@ -1,185 +1,185 @@
/**
* @file hertz_3D.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date Fri Apr 4 11:30:00 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief File used to obtain 3D implicit contact results and compare with
* Hertz theory
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <chrono>
#include "contact_impl.hh"
using namespace akantu;
using std::cout;
using std::endl;
using std::setw;
using std::setprecision;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 3;
// type definitions
typedef Point<dim> point_type;
typedef BoundingBox<dim> bbox_type;
typedef SolidMechanicsModel model_type;
typedef Contact<dim, MasterAssignator,
SelectResolution<_static, _augmented_lagrangian> >
contact_type;
typedef std::chrono::high_resolution_clock clock;
typedef std::chrono::seconds seconds;
clock::time_point t0 = clock::now();
initialize("steel.dat", argc, argv);
// create mesh
Mesh mesh(dim);
// read mesh
mesh.read("hertz_3D.msh");
// create model
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
// initialize material
model.initFull(opt);
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// optimal value of penalty multiplier
cd[Alpha] = 0.05;
cd[Multiplier_tol] = 1.e-2;
cd[Newton_tol] = 1.e-2;
cd[Verbose] = true;
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
// call update current position to be able to call later
// the function to get current positions
model.updateCurrentPosition();
// get physical names from Gmsh file
mesh.createGroupsFromMeshData<std::string>("physical_names");
// set-up bounding box to include slave nodes that lie inside it
Real l1 = 1.;
Real l2 = 0.2;
Real l3 = 1.;
point_type c1(-l1 / 2, -l2 / 2, -l3 / 2);
point_type c2(l1 / 2, l2 / 2, l3 / 2);
bbox_type bb(c1, c2);
// get areas for the nodes of the circle
// this is done by applying a unit pressure to the contact surface elements
model.applyBC(BC::Neumann::FromHigherDim(Matrix<Real>::eye(3, 1.)),
"contact_surface");
Array<Real> &areas = model.getForce();
// loop over contact surface nodes and store node areas
ElementGroup &eg = mesh.getElementGroup("contact_surface");
Array<Real> &coords = mesh.getNodes();
cout << "- Adding areas to slave nodes. " << endl;
for (auto nit = eg.node_begin(); nit != eg.node_end(); ++nit) {
point_type p(&coords(*nit));
// ignore slave node if it doesn't lie within the bounding box
if (!(bb & p))
continue;
cd.addSlave(*nit);
// compute area contributing to the slave node
Real a = 0.;
for (UInt i = 0; i < dim; ++i)
a += pow(areas(*nit, i), 2.);
cd.addArea(*nit, sqrt(a));
}
// set force value to zero
areas.clear();
// add master surface to find pairs
cd.searchSurface("rigid_surface");
// apply boundary conditions for the rigid plane
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "bottom_body");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "bottom_body");
model.applyBC(BC::Dirichlet::FixedValue(0., _z), "bottom_body");
// block z-disp in extreme points of top surface
model.getBlockedDOFs()(1, 2) = true;
model.getBlockedDOFs()(2, 2) = true;
// block x-disp in extreme points of top surface
model.getBlockedDOFs()(3, 0) = true;
model.getBlockedDOFs()(4, 0) = true;
const size_t steps = 30;
Real data[3][steps]; // store results for printing
Real step = 0.001; // top displacement increment
size_t k = 0;
for (Real delta = 0; delta <= step * steps; delta += step) {
// apply displacement to the top surface of the half-sphere
model.applyBC(BC::Dirichlet::FixedValue(-delta, _y), "top_surface");
// solve contact step, this function also dumps Paraview files
solveContactStep<_uzawa>(cd);
// solveContactStep<_generalized_newton>(cd);
data[0][k] = delta;
data[1][k] = cd.getForce();
data[2][k] = cd.getMaxPressure();
++k;
}
// print results
size_t w = 14;
cout << setprecision(4);
cout << endl << setw(w) << "Disp." << setw(w) << "Force" << setw(w)
<< "Max pressure" << endl;
for (size_t i = 0; i < steps; ++i)
cout << setw(w) << data[0][i] << setw(w) << data[1][i] << setw(w)
<< data[2][i] << endl;
clock::time_point t1 = clock::now();
seconds total_s = std::chrono::duration_cast<seconds>(t1 - t0);
cout << "*** INFO *** Simulation took " << total_s.count() << " s" << endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/contact/tetrahedra.cc b/examples/contact/tetrahedra.cc
index 54dc49336..7707216ac 100644
--- a/examples/contact/tetrahedra.cc
+++ b/examples/contact/tetrahedra.cc
@@ -1,109 +1,109 @@
/**
* @file tetrahedra.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date Tue Jan 14 09:38:00 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief File used to obtain contact results for a simple tetrahedra test
- *
+ *
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
//#include "implicit_contact_manager.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 3;
typedef SolidMechanicsModel model_type;
// typedef ContactData<dim,model_type> contact_type;
typedef Contact <dim, MasterAssignator, SelectResolution <_static, _augmented_lagrangian> >
contact_type;
// initialize akantu
initialize("steel.dat", argc, argv);
// create and read mesh
Mesh mesh(dim);
mesh.read("tetrahedra.msh");
// create model
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
// initialize model
model.initFull(opt);
// paraview output
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
// create conctact object
contact_type cd(argc, argv, model);
// add slave node of the tip of the top tetrahedron
cd.addSlave(4);
// parameters
cd[Verbose] = true;
// add search surface
cd.searchSurface("master");
// apply boundary conditions
mesh.createGroupsFromMeshData<std::string>("physical_names");
using BC::Dirichlet::FixedValue;
// model.applyBC(FixedValue(0., _y), "top_surface");
model.applyBC(FixedValue(0., _x), "top_surface");
model.applyBC(FixedValue(0., _z), "top_surface");
model.applyBC(FixedValue(0., _x), "bottom_surface");
model.applyBC(FixedValue(0., _y), "bottom_surface");
model.applyBC(FixedValue(0., _z), "bottom_surface");
// model.applyBC(FixedValue(0., _x), "master");
// model.applyBC(FixedValue(0., _y), "master");
// model.applyBC(FixedValue(0., _z), "master");
Real U = 2;
Real Du = 0.01;
for (Real u = Du; u<=U; u += Du) {
// model.applyBC(FixedValue(u, _x), "top_surface");
model.applyBC(FixedValue(-u, _y), "top_surface");
// solve contact step (no need to call solve on the model object)
// solveContactStep<_uzawa>(cd);
solveContactStep<_generalized_newton>(cd);
}
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/embedded/CMakeLists.txt b/examples/embedded/CMakeLists.txt
index db215aa62..64cc2b2ab 100644
--- a/examples/embedded/CMakeLists.txt
+++ b/examples/embedded/CMakeLists.txt
@@ -1,42 +1,41 @@
#===============================================================================
# @file CMakeLists.txt
#
-# @author Lucas Frérot <lucas.frerot@epfl.ch>
+# @author Lucas Frerot <lucas.frerot@epfl.ch>
#
-# @date creation: Wed Jul 22 2015
-# @date last modification: Wed Jul 22 2015
+# @date creation: Tue Dec 01 2015
#
# @brief configuration for embedded example
#
# @section LICENSE
#
-# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
register_example(embedded embedded.cc USE CGAL)
add_mesh(concrete_mesh concrete.geo 2 1)
add_mesh(reinforcement_mesh reinforcement.geo 1 1)
add_dependencies(embedded concrete_mesh)
add_dependencies(embedded reinforcement_mesh)
#===============================================================================
file(COPY material.dat DESTINATION .)
diff --git a/examples/embedded/embedded.cc b/examples/embedded/embedded.cc
index 3bf33542b..8625b735f 100644
--- a/examples/embedded/embedded.cc
+++ b/examples/embedded/embedded.cc
@@ -1,108 +1,107 @@
/**
- * @file embedded.cc
+ * @file embedded.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Wed Jul 22 2015
- * @date last modification: Wed Jul 22 2015
+ * @date creation: Tue Dec 01 2015
*
- * @brief This code gives an example of a simulation using the embedded model
+ * @brief This code gives an example of a simulation using the embedded model
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "embedded_interface_model.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt dim = 2;
// Loading the concrete mesh
Mesh mesh(dim);
mesh.read("concrete.msh");
// Necessary to define physical names
mesh.createGroupsFromMeshData<std::string>("physical_names");
// Loading the reinforcement mesh
Mesh reinforcement_mesh(dim, "reinforcement_mesh");
// Exception is raised because reinforcement
// mesh contains only segments, i.e. 1D elements
try {
reinforcement_mesh.read("reinforcement.msh");
} catch (debug::Exception & e) {}
// Necessary to define physical names as well
reinforcement_mesh.createGroupsFromMeshData<std::string>("physical_names");
// Model creation
EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
model.initFull(EmbeddedInterfaceModelOptions(_static));
// Boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "XBlocked");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "YBlocked");
Vector<Real> force(dim);
force(0) = 0.0;
force(1) = -1.0;
model.applyBC(BC::Neumann::FromTraction(force), "Force");
// Dumping the concrete
model.setBaseName("concrete");
model.addDumpFieldVector("displacement");
model.addDumpFieldVector("force" );
model.addDumpFieldVector("residual" );
model.addDumpFieldTensor("stress" );
// Dumping the reinforcement
model.setBaseNameToDumper("reinforcement", "reinforcement");
model.addDumpFieldTensorToDumper("reinforcement", "stress_embedded"); // dumping stress in reinforcement
// Assemble global stiffness matrix
model.assembleStiffnessMatrix();
// Update residual
model.updateResidual();
// Solve
Real error;
bool converged = model.solveStep<_scm_newton_raphson_tangent_not_computed, _scc_residual>(1e-6, error, 1);
if (!converged)
std::cerr << "Model did not converge, error = " << error << std::endl;
// Dumping model
model.dump();
model.dump("reinforcement");
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/explicit/CMakeLists.txt b/examples/explicit/CMakeLists.txt
index 744b63528..bab300567 100644
--- a/examples/explicit/CMakeLists.txt
+++ b/examples/explicit/CMakeLists.txt
@@ -1,40 +1,39 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
# @author Cyprien Wolff <cyprien.wolff@epfl.ch>
#
-# @date creation: Mon Apr 16 2012
-# @date last modification: Thu Nov 01 2012
+# @date creation: Sun Oct 19 2014
#
# @brief configuration for explicit example
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
register_example(explicit_dynamic explicit_dynamic.cc)
add_mesh(explicit_dynamic_mesh bar.geo 3 1)
add_dependencies(explicit_dynamic explicit_dynamic_mesh)
#===============================================================================
file(COPY material.dat DESTINATION .)
diff --git a/examples/explicit/explicit_dynamic.cc b/examples/explicit/explicit_dynamic.cc
index b3865a8bb..33ffe96f7 100644
--- a/examples/explicit/explicit_dynamic.cc
+++ b/examples/explicit/explicit_dynamic.cc
@@ -1,109 +1,109 @@
/**
* @file explicit_dynamic.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
*
- * @date creation: Mon Apr 16 2012
- * @date last modification: Tue Jun 10 2014
+ * @date creation: Sun Jul 12 2015
+ * @date last modification: Thu Aug 06 2015
*
* @brief This code refers to the explicit dynamic example from the user manual
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include <iostream>
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 3;
const Real pulse_width = 2.;
const Real A = 0.01;
Real time_step;
Real time_factor = 0.8;
UInt max_steps = 1000;
Mesh mesh(spatial_dimension);
mesh.computeBoundingBox();
mesh.read("bar.msh");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
time_step = model.getStableTimeStep();
std::cout << "Time Step = " << time_step * time_factor << "s ("<< time_step << "s)" << std::endl;
model.setTimeStep(time_step * time_factor);
/// boundary and initial conditions
Array<Real> & displacement = model.getDisplacement();
const Array<Real> & nodes = mesh.getNodes();
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
Real x = nodes(n);
// Sinus * Gaussian
Real L = pulse_width;
Real k = 0.1 * 2 * M_PI * 3 / L;
displacement(n) = A * sin(k * x) * exp(-(k * x) * (k * x) / (L * L));
}
std::ofstream energy;
energy.open("energy.csv");
energy << "id,rtime,epot,ekin,tot" << std::endl;
model.setBaseName("explicit_dynamic");
model.addDumpField("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("stress" );
model.dump();
for(UInt s = 1; s <= max_steps; ++s) {
model.solveStep();
Real epot = model.getEnergy("potential");
Real ekin = model.getEnergy("kinetic");
energy << s << "," << s*time_step << ","
<< epot << ","
<< ekin << ","
<< epot + ekin << ","
<< std::endl;
if(s % 10 == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
model.dump();
}
energy.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/heat_transfer/CMakeLists.txt b/examples/heat_transfer/CMakeLists.txt
index 01a75abb7..dea7e8cac 100644
--- a/examples/heat_transfer/CMakeLists.txt
+++ b/examples/heat_transfer/CMakeLists.txt
@@ -1,42 +1,41 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
-# @date creation: Fri Jun 06 2014
-# @date last modification: Fri Jun 06 2014
+# @date creation: Sun Oct 19 2014
#
# @brief configuration for heat transfer example
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
register_example(explicit_heat_transfer explicit_heat_transfer.cc)
add_mesh(explicit_heat_transfer_mesh square.geo 2 2)
add_dependencies(explicit_dynamic explicit_heat_transfer_mesh)
#===============================================================================
file(COPY material.dat DESTINATION .)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
diff --git a/examples/heat_transfer/explicit_heat_transfer.cc b/examples/heat_transfer/explicit_heat_transfer.cc
index da251ad94..9ee6c5042 100644
--- a/examples/heat_transfer/explicit_heat_transfer.cc
+++ b/examples/heat_transfer/explicit_heat_transfer.cc
@@ -1,113 +1,112 @@
/**
* @file explicit_heat_transfer.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
- * @date creation: Fri Jun 06 2014
- * @date last modification: Fri Jun 06 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "heat_transfer_model.hh"
#include "pbc_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
/* -------------------------------------------------------------------------- */
akantu::UInt spatial_dimension = 2;
std::string base_name;
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
//create mesh
akantu::Mesh mesh(spatial_dimension);
mesh.read("square.msh");
akantu::HeatTransferModel model(mesh);
//initialize everything
model.initFull();
//assemble the lumped capacity
model.assembleCapacityLumped();
//get stable time step
akantu::Real time_step = model.getStableTimeStep()*0.8;
cout<<"time step is:" << time_step << endl;
model.setTimeStep(time_step);
//boundary conditions
const akantu::Array<akantu::Real> & nodes = model.getFEEngine().getMesh().getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<akantu::Real> & temperature = model.getTemperature();
double length;
length = 1.;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
temperature(i) = 100.;
akantu::Real dx = nodes(i,0) - length/4.;
akantu::Real dy = 0.0;
akantu::Real dz = 0.0;
if (spatial_dimension > 1) dy = nodes(i,1) - length/4.;
if (spatial_dimension == 3) dz = nodes(i,2) - length/4.;
akantu::Real d = sqrt(dx*dx + dy*dy + dz*dz);
// if(dx < 0.0){
if(d < 0.1){
boundary(i) = true;
temperature(i) = 300.;
}
}
model.updateResidual();
model.setBaseName("heat_transfer_square2d");
model.addDumpField("temperature" );
model.addDumpField("temperature_rate");
model.addDumpField("residual" );
model.addDumpField("capacity_lumped" );
model.dump();
//main loop
int max_steps = 15000;
for(int i=0; i<max_steps; i++)
{
model.explicitPred();
model.updateResidual();
model.solveExplicitLumped();
model.explicitCorr();
if(i % 100 == 0) model.dump();
if(i % 10 == 0)
std::cout << "Step " << i << "/" << max_steps << std::endl;
}
cout<< "\n\n Stable Time Step is : " << time_step << "\n \n" <<endl;
return 0;
}
diff --git a/examples/implicit/CMakeLists.txt b/examples/implicit/CMakeLists.txt
index 27abfc60e..d068427c7 100644
--- a/examples/implicit/CMakeLists.txt
+++ b/examples/implicit/CMakeLists.txt
@@ -1,44 +1,43 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Fri Feb 24 2012
-# @date last modification: Thu Jun 05 2014
+# @date creation: Sun Oct 19 2014
#
# @brief configuration implicit tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
#===============================================================================
register_example(implicit_dynamic implicit_dynamic.cc)
add_mesh(implicit_dynamic_mesh beam.geo 3 2)
add_dependencies(implicit_dynamic implicit_dynamic_mesh)
#===============================================================================
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/material_dynamic.dat
${CMAKE_CURRENT_BINARY_DIR}/material_dynamic.dat
COPYONLY
)
diff --git a/examples/implicit/implicit_dynamic.cc b/examples/implicit/implicit_dynamic.cc
index 9fadb07f6..bfbe85603 100644
--- a/examples/implicit/implicit_dynamic.cc
+++ b/examples/implicit/implicit_dynamic.cc
@@ -1,147 +1,146 @@
/**
* @file implicit_dynamic.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Feb 24 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief This code refers to the implicit dynamic example from the user manual
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include <iostream>
using namespace akantu;
/* -------------------------------------------------------------------------- */
const Real bar_length = 10.;
const Real bar_height = 1.;
const Real bar_depth = 1.;
const Real F = 5e3;
const Real L = bar_length;
const Real I = bar_depth * bar_height * bar_height * bar_height / 12.;
const Real E = 12e7;
const Real rho = 1000;
const Real m = rho * bar_height * bar_depth;
static Real w(UInt n) {
return n*n*M_PI*M_PI/(L*L)*sqrt(E*I/m);
}
static Real analytical_solution(Real time) {
return 2*F*L*L*L/(pow(M_PI, 4)*E*I) * ((1. - cos(w(1)*time)) + (1. - cos(w(3)*time))/81. + (1. - cos(w(5)*time))/625.);
}
const UInt spatial_dimension = 2;
const Real time_step = 1e-4;
const Real max_time = 0.62;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
initialize("material_dynamic.dat", argc, argv);
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
MeshPartition * partition = NULL;
if(prank == 0) {
mesh.read("beam.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
SolidMechanicsModel model(mesh);
model.initParallel(partition);
mesh.createGroupsFromMeshData<std::string>("physical_names");
/// model initialization
model.initFull(SolidMechanicsModelOptions(_implicit_dynamic));
Material &mat = model.getMaterial(0);
mat.setParam("E", E);
mat.setParam("rho", rho);
model.getMassMatrix().saveMatrix("M.mtx");
Array<Real> & force = model.getForce();
Array<Real> & displacment = model.getDisplacement();
// boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "blocked");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "blocked");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "roller");
const Array<UInt> & trac_nodes = mesh.getElementGroup("traction").getNodes();
bool dump_node = false;
if(trac_nodes.getSize() > 0 && mesh.isLocalOrMasterNode(trac_nodes(0))) {
force(trac_nodes(0), 1) = F;
dump_node = true;
}
// output setup
std::ofstream pos;
pos.open("position.csv");
if(!pos.good()) AKANTU_DEBUG_ERROR("Cannot open file \"position.csv\"");
pos << "id,time,position,solution" << std::endl;
model.setBaseName("dynamic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.dump();
model.setTimeStep(time_step);
/// time loop
Real time = 0.;
for (UInt s = 1; time < max_time; ++s, time += time_step) {
if(prank == 0)
std::cout << s << "\r" << std::flush;
model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-12, 100);
if(dump_node)
pos << s << ","
<< time << ","
<< displacment(trac_nodes(0), 1) << ","
<< analytical_solution(s*time_step) << std::endl;
if(s % 100 == 0)
model.dump();
}
std::cout << std::endl;
pos.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/io/CMakeLists.txt b/examples/io/CMakeLists.txt
index fdbbc040b..1128600c0 100644
--- a/examples/io/CMakeLists.txt
+++ b/examples/io/CMakeLists.txt
@@ -1,30 +1,33 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Fabian Barras <fabian.barras@epfl.ch>
#
-# @date creation: Fri Aug 14 2015
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 14 2015
#
# @brief CMakeLists for Input/Output examples
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
+
add_example(dumper "Examples on how to use DumperIOHelper to output data" PACKAGE iohelper)
add_example(parser "Examples on how to input data from text file in Akantu" PACKAGE core)
diff --git a/examples/io/dumper/CMakeLists.txt b/examples/io/dumper/CMakeLists.txt
index 35579da1c..3235c7768 100644
--- a/examples/io/dumper/CMakeLists.txt
+++ b/examples/io/dumper/CMakeLists.txt
@@ -1,51 +1,54 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Fabian Barras <fabian.barras@epfl.ch>
#
-# @date creation: Fri Aug 14 2015
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Aug 17 2015
#
# @brief CMakeLists for DumperIOHelper examples
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(swiss_train swiss_train.geo 2 1)
add_library(locomotive_tools
locomotive_tools.cc
locomotive_tools.hh
)
register_example(dumper_low_level
dumper_low_level.cc
USE IOHelper
DEPENDS swiss_train locomotive_tools
DIRECTORIES_TO_CREATE paraview
)
register_example(dumpable_interface
dumpable_interface.cc
USE IOHelper
DEPENDS swiss_train locomotive_tools
DIRECTORIES_TO_CREATE paraview
)
diff --git a/examples/io/dumper/dumpable_interface.cc b/examples/io/dumper/dumpable_interface.cc
index 456bdd55d..bfed4045a 100644
--- a/examples/io/dumper/dumpable_interface.cc
+++ b/examples/io/dumper/dumpable_interface.cc
@@ -1,185 +1,189 @@
/**
- * @file example_dumpable_interface.cc
+ * @file dumpable_interface.cc
+ *
* @author Fabian Barras <fabian.barras@epfl.ch>
- * @date Thu Jul 2 14:34:41 2015
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Mon Aug 17 2015
+ * @date last modification: Mon Aug 31 2015
*
* @brief Example of dumper::Dumpable interface.
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include "element_group.hh"
#include "dumper_paraview.hh"
#include "dumpable_inline_impl.hh"
#include "group_manager_inline_impl.cc"
/* -------------------------------------------------------------------------- */
#include "locomotive_tools.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
/*
In this example, we present dumper::Dumpable which is an interface
for other classes who want to dump themselves.
Several classes of Akantu inheritate from Dumpable (Model, Mesh, ...).
In this example we reproduce the same tasks as example_dumper_low_level.cc
using this time Dumpable interface inherted by Mesh, NodeGroup and
ElementGroup.
It is then advised to read first example_dumper_low_level.cc.
*/
initialize(argc, argv);
// To start let us load the swiss train mesh and its mesh data information.
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("swiss_train.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
/*
swiss_train.msh has the following physical groups that can be viewed with
GMSH:
"$MeshFormat
2.2 0 8
$EndMeshFormat
$PhysicalNames
6
2 1 "red"
2 2 "white"
2 3 "lwheel_1"
2 4 "lwheel_2"
2 5 "rwheel_2"
2 6 "rwheel_1"
$EndPhysicalNames
..."
*/
// Grouping nodes and elements belonging to train wheels (=four mesh data).
ElementGroup & wheels_elements =
mesh.createElementGroup("wheels", spatial_dimension);
wheels_elements.append(mesh.getElementGroup("lwheel_1"));
wheels_elements.append(mesh.getElementGroup("lwheel_2"));
wheels_elements.append(mesh.getElementGroup("rwheel_1"));
wheels_elements.append(mesh.getElementGroup("rwheel_2"));
const Array<UInt> & lnode_1 = (mesh.getElementGroup("lwheel_1")).getNodes();
const Array<UInt> & lnode_2 = (mesh.getElementGroup("lwheel_2")).getNodes();
const Array<UInt> & rnode_1 = (mesh.getElementGroup("rwheel_1")).getNodes();
const Array<UInt> & rnode_2 = (mesh.getElementGroup("rwheel_2")).getNodes();
Array<Real> & node = mesh.getNodes();
UInt nb_nodes = mesh.getNbNodes();
// This time a 2D Array is created and a padding size of 3 is passed to
// NodalField in order to warp train deformation on Paraview.
Array<Real> displacement(nb_nodes, spatial_dimension);
// Create an ElementTypeMapArray for the colour
ElementTypeMapArray<UInt> colour("colour");
mesh.initElementTypeMapArray(colour, 1, spatial_dimension, false, _ek_regular,
true);
/* ------------------------------------------------------------------------ */
/* Creating dumpers */
/* ------------------------------------------------------------------------ */
// Create dumper for the complete mesh and register it as default dumper.
DumperParaview dumper("train", "./paraview/dumpable", false);
mesh.registerExternalDumper(dumper, "train", true);
mesh.addDumpMesh(mesh);
// The dumper for the filtered mesh can be directly taken from the
// ElementGroup and then registered as "wheels_elements" dumper.
DumperIOHelper & wheels =
mesh.getGroupDumper("paraview_wheels", "wheels");
mesh.registerExternalDumper(wheels, "wheels");
mesh.setDirectoryToDumper("wheels", "./paraview/dumpable");
// Arrays and ElementTypeMapArrays can be added as external fields directly
mesh.addDumpFieldExternal("displacement", displacement);
ElementTypeMapArrayFilter<UInt> filtered_colour(
colour, wheels_elements.getElements());
dumper::Field * colour_field_wheel =
new dumper::ElementalField<UInt, Vector, true>(filtered_colour);
mesh.addDumpFieldExternal("color", colour_field_wheel);
mesh.addDumpFieldExternalToDumper("wheels", "displacement",
displacement);
mesh.addDumpFieldExternalToDumper("wheels", "colour", colour);
// For some specific cases the Fields should be created, as when you want to
// pad an array
dumper::Field * displacement_vector_field =
mesh.createNodalField(&displacement, "all", 3);
mesh.addDumpFieldExternal("displacement_as_paraview_vector",
displacement_vector_field);
mesh.addDumpFieldExternalToDumper("wheels",
"displacement_as_paraview_vector",
displacement_vector_field);
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
// Fill the ElementTypeMapArray colour.
fillColour(mesh, colour);
/// Apply displacement and wheels rotation.
Real tot_displacement = 50.;
Real radius = 1.;
UInt nb_steps = 100;
Real theta = tot_displacement / radius;
Vector<Real> l_center(spatial_dimension);
Vector<Real> r_center(spatial_dimension);
for (UInt i = 0; i < spatial_dimension; ++i) {
l_center(i) = node(14, i);
r_center(i) = node(2, i);
}
for (UInt i = 0; i < nb_steps; ++i) {
displacement.clear();
Real step_ratio = Real(i) / Real(nb_steps);
Real angle = step_ratio * theta;
applyRotation(l_center, angle, node, displacement, lnode_1);
applyRotation(l_center, angle, node, displacement, lnode_2);
applyRotation(r_center, angle, node, displacement, rnode_1);
applyRotation(r_center, angle, node, displacement, rnode_2);
for (UInt j = 0; j < nb_nodes; ++j) {
displacement(j, _x) += step_ratio * tot_displacement;
}
/// Dump call is finally made through Dumpable interface.
mesh.dump();
mesh.dump("wheels");
}
finalize();
return 0;
}
diff --git a/examples/io/dumper/dumper_low_level.cc b/examples/io/dumper/dumper_low_level.cc
index d7a25c6e5..0a778585e 100644
--- a/examples/io/dumper/dumper_low_level.cc
+++ b/examples/io/dumper/dumper_low_level.cc
@@ -1,192 +1,195 @@
/**
* @file dumper_low_level.cc
+ *
* @author Fabian Barras <fabian.barras@epfl.ch>
- * @date Thu Jul 2 14:34:41 2015
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Mon Aug 17 2015
*
* @brief Example of dumper::DumperIOHelper low-level methods.
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include "group_manager.hh"
#include "element_group.hh"
#include "dumper_elemental_field.hh"
#include "dumper_nodal_field.hh"
#include "dumper_paraview.hh"
#include "locomotive_tools.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
/* This example aims at illustrating how to manipulate low-level methods of
DumperIOHelper.
The aims is to visualize a colorized moving train with Paraview */
initialize(argc, argv);
// To start let us load the swiss train mesh and its mesh data information.
// We aknowledge here a weel-known swiss industry for mesh donation.
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("swiss_train.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
Array<Real> & nodes = mesh.getNodes();
UInt nb_nodes = mesh.getNbNodes();
/* swiss_train.msh has the following physical groups that can be viewed with
GMSH:
"$MeshFormat
2.2 0 8
$EndMeshFormat
$PhysicalNames
6
2 1 "red"
2 2 "white"
2 3 "lwheel_1"
2 4 "lwheel_2"
2 5 "rwheel_2"
2 6 "rwheel_1"
$EndPhysicalNames
..."
*/
// Grouping nodes and elements belonging to train wheels (=four mesh data)
ElementGroup & wheels_elements =
mesh.createElementGroup("wheels", spatial_dimension);
wheels_elements.append(mesh.getElementGroup("lwheel_1"));
wheels_elements.append(mesh.getElementGroup("lwheel_2"));
wheels_elements.append(mesh.getElementGroup("rwheel_1"));
wheels_elements.append(mesh.getElementGroup("rwheel_2"));
const Array<UInt> & lnode_1 = (mesh.getElementGroup("lwheel_1")).getNodes();
const Array<UInt> & lnode_2 = (mesh.getElementGroup("lwheel_2")).getNodes();
const Array<UInt> & rnode_1 = (mesh.getElementGroup("rwheel_1")).getNodes();
const Array<UInt> & rnode_2 = (mesh.getElementGroup("rwheel_2")).getNodes();
/* Note this Array is constructed with three components in order to warp train
deformation on Paraview. A more appropriate way to do this is to set a
padding in the NodalField (See example_dumpable_interface.cc.) */
Array<Real> displacement(nb_nodes, 3);
// ElementalField are constructed with an ElementTypeMapArray.
ElementTypeMapArray<UInt> colour;
mesh.initElementTypeMapArray(colour, 1, spatial_dimension, false, _ek_regular,
true);
/* ------------------------------------------------------------------------ */
/* Dumper creation */
/* ------------------------------------------------------------------------ */
// Creation of two DumperParaview. One for full mesh, one for a filtered
// mesh.
DumperParaview dumper("train", "./paraview/dumper", false);
DumperParaview wheels("wheels", "./paraview/dumper", false);
// Register the full mesh
dumper.registerMesh(mesh);
// Register a filtered mesh limited to nodes and elements from wheels groups
wheels.registerFilteredMesh(mesh, wheels_elements.getElements(),
wheels_elements.getNodes());
// Generate an output file of the two mesh registered.
dumper.dump();
wheels.dump();
/* At this stage no fields are attached to the two dumpers. To do so, a
dumper::Field object has to be created. Several types of dumper::Field
exist. In this example we present two of them.
NodalField to describe nodal displacements of our train.
ElementalField handling the color of our different part.
*/
// NodalField are constructed with an Array.
dumper::Field * displ_field = new dumper::NodalField<Real>(displacement);
dumper::Field * colour_field = new dumper::ElementalField<UInt>(colour);
// Register the freshly created fields to our dumper.
dumper.registerField("displacement", displ_field);
dumper.registerField("colour", colour_field);
// For the dumper wheels, fields have to be filtered at registration.
// Filtered NodalField can be simply registered by adding an Array<UInt>
// listing the nodes.
dumper::Field * displ_field_wheel = new dumper::NodalField<Real, true>(
displacement, 0, 0, &(wheels_elements.getNodes()));
wheels.registerField("displacement", displ_field_wheel);
// For the ElementalField, an ElementTypeMapArrayFilter has to be created.
ElementTypeMapArrayFilter<UInt> filtered_colour(
colour, wheels_elements.getElements());
dumper::Field * colour_field_wheel =
new dumper::ElementalField<UInt, Vector, true>(filtered_colour);
wheels.registerField("colour", colour_field_wheel);
/* ------------------------------------------------------------------------ */
// Now that the dumpers are created and the fields are associated, let's
// paint and move the train!
// Fill the ElementTypeMapArray colour according to mesh data information.
fillColour(mesh, colour);
// Apply displacement and wheels rotation.
Real tot_displacement = 50.;
Real radius = 1.;
UInt nb_steps = 100;
Real theta = tot_displacement / radius;
Vector<Real> l_center(3);
Vector<Real> r_center(3);
for (UInt i = 0; i < spatial_dimension; ++i) {
l_center(i) = nodes(14, i);
r_center(i) = nodes(2, i);
}
for (UInt i = 0; i < nb_steps; ++i) {
displacement.clear();
Real angle = (Real)i / (Real)nb_steps * theta;
applyRotation(l_center, angle, nodes, displacement, lnode_1);
applyRotation(l_center, angle, nodes, displacement, lnode_2);
applyRotation(r_center, angle, nodes, displacement, rnode_1);
applyRotation(r_center, angle, nodes, displacement, rnode_2);
for (UInt j = 0; j < nb_nodes; ++j) {
displacement(j, 0) += (Real)i / (Real)nb_steps * tot_displacement;
}
// Output results after each moving steps for main and wheel dumpers.
dumper.dump();
wheels.dump();
}
finalize();
return 0;
}
diff --git a/examples/io/dumper/locomotive_tools.cc b/examples/io/dumper/locomotive_tools.cc
index 19971cf22..e8b7d1ac1 100644
--- a/examples/io/dumper/locomotive_tools.cc
+++ b/examples/io/dumper/locomotive_tools.cc
@@ -1,87 +1,87 @@
/**
* @file locomotive_tools.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date Mon Aug 17 14:23:22 2015
+ * @date creation: Mon Aug 17 2015
*
* @brief Common functions for the dumper examples
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include "aka_types.hh"
using namespace akantu;
/* -------------------------------------------------------------------------- */
void applyRotation(const Vector<Real> & center, Real angle,
const Array<Real> & nodes, Array<Real> & displacement,
const Array<UInt> & node_group) {
Array<Real>::const_vector_iterator nodes_it =
nodes.begin(nodes.getNbComponent());
Array<Real>::vector_iterator disp_it = displacement.begin(center.size());
Array<UInt>::const_scalar_iterator node_num_it = node_group.begin();
Array<UInt>::const_scalar_iterator node_num_end = node_group.end();
Vector<Real> pos_rel(center.size());
for (; node_num_it != node_num_end; ++node_num_it) {
const Vector<Real> pos = nodes_it[*node_num_it];
for (UInt i = 0; i < pos.size(); ++i)
pos_rel(i) = pos(i);
Vector<Real> dis = disp_it[*node_num_it];
pos_rel -= center;
Real radius = pos_rel.norm();
if (std::abs(radius) < Math::getTolerance()) continue;
Real phi_i = std::acos(pos_rel(_x) / radius);
if (pos_rel(_y) < 0) phi_i *= -1;
dis(_x) = std::cos(phi_i - angle) * radius - pos_rel(_x);
dis(_y) = std::sin(phi_i - angle) * radius - pos_rel(_y);
}
}
/* -------------------------------------------------------------------------- */
void fillColour(const Mesh & mesh,
ElementTypeMapArray<UInt> & colour) {
const ElementTypeMapArray<std::string> & phys_data =
mesh.getData<std::string>("physical_names");
const Array<std::string> & txt_colour = phys_data(_triangle_3);
Array<UInt> & id_colour = colour(_triangle_3);
for (UInt i = 0; i < txt_colour.getSize(); ++i) {
std::string phy_name = txt_colour(i);
if (phy_name == "red")
id_colour(i) = 3;
else if (phy_name == "white" || phy_name == "lwheel_1" ||
phy_name == "rwheel_1")
id_colour(i) = 2;
else
id_colour(i) = 1;
}
}
diff --git a/examples/io/dumper/locomotive_tools.hh b/examples/io/dumper/locomotive_tools.hh
index 38cb70a80..a0e9fe13d 100644
--- a/examples/io/dumper/locomotive_tools.hh
+++ b/examples/io/dumper/locomotive_tools.hh
@@ -1,38 +1,40 @@
/**
* @file locomotive_tools.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date Mon Aug 17 14:25:25 2015
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Mon Aug 17 2015
*
* @brief interface for the common tools
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
void applyRotation(const ::akantu::Vector<::akantu::Real> & center,
::akantu::Real angle,
const ::akantu::Array<::akantu::Real> & nodes,
::akantu::Array<::akantu::Real> & displacement,
const ::akantu::Array<::akantu::UInt> & node_group);
void fillColour(const ::akantu::Mesh & mesh,
::akantu::ElementTypeMapArray<::akantu::UInt> & colour);
diff --git a/examples/io/parser/CMakeLists.txt b/examples/io/parser/CMakeLists.txt
index b304736f0..baa3dbf90 100644
--- a/examples/io/parser/CMakeLists.txt
+++ b/examples/io/parser/CMakeLists.txt
@@ -1,44 +1,47 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Fabian Barras <fabian.barras@epfl.ch>
#
-# @date creation: Mon Dec 14 09:07:44 2015
-#
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 14 2015
+#
# @brief Tests insertion of cohesive elements
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(swiss_cheese swiss_cheese.geo 2 2)
register_example(example_parser
example_parser.cc
USE IOHelper
DEPENDS swiss_cheese
DIRECTORIES_TO_CREATE paraview
)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/input_file.dat
${CMAKE_CURRENT_BINARY_DIR}/input_file.dat
COPYONLY
)
diff --git a/examples/io/parser/example_parser.cc b/examples/io/parser/example_parser.cc
index b431faf80..e2fed9389 100644
--- a/examples/io/parser/example_parser.cc
+++ b/examples/io/parser/example_parser.cc
@@ -1,80 +1,82 @@
/**
* @file example_parser.cc
+ *
* @author Fabian Barras <fabian.barras@epfl.ch>
- * @date Mon Dec 14 09:45:20 2015
+ *
+ * @date creation: Mon Dec 14 2015
*
* @brief Example on how to parse input text file
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
// Precise in initialize the name of the text input file to parse.
initialize("input_file.dat", argc, argv);
// Get the user ParserSection.
const ParserSection & usersect = getUserParser();
// getParameterValue() allows to extract data associated to a given parameter name
// and cast it in the desired type set as template paramter.
Mesh mesh(usersect.getParameterValue<UInt>("spatial_dimension"));
mesh.read(usersect.getParameterValue<std::string>("mesh_file"));
// getParameter() can be used with variable declaration (destination type is explicitly known).
UInt max_iter = usersect.getParameter("max_nb_iterations");
Real precision = usersect.getParameter("precision");
// Following NumPy convention, data can be interpreted as Vector or Matrix structures.
Matrix<Real> eigen_stress = usersect.getParameter("stress");
SolidMechanicsModel model(mesh);
mesh.createGroupsFromMeshData<std::string>("physical_names");
model.initFull(SolidMechanicsModelOptions(_static));
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), usersect.getParameterValue<std::string>("outter_crust"));
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), usersect.getParameterValue<std::string>("outter_crust"));
model.applyBC(BC::Neumann::FromStress(eigen_stress), usersect.getParameterValue<std::string>("inner_holes"));
model.setDirectory("./paraview");
model.setBaseName("swiss_cheese");
model.addDumpFieldVector("displacement");
model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(precision, max_iter);
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/new_material/CMakeLists.txt b/examples/new_material/CMakeLists.txt
index 061d6f258..4123ec087 100644
--- a/examples/new_material/CMakeLists.txt
+++ b/examples/new_material/CMakeLists.txt
@@ -1,48 +1,47 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
#
-# @date creation: Fri Apr 20 2012
-# @date last modification: Thu Nov 01 2012
+# @date creation: Sun Oct 19 2014
#
# @brief CMakeFile for new material example
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
#===============================================================================
add_mesh(new_local_material_barre_trou_mesh barre_trou.geo 2 2)
register_example(new_local_material local_material_damage.cc new_local_material.cc)
add_dependencies(new_local_material
new_local_material_barre_trou_mesh
)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/material.dat
${CMAKE_CURRENT_BINARY_DIR}/material.dat
COPYONLY
)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
diff --git a/examples/new_material/local_material_damage.cc b/examples/new_material/local_material_damage.cc
index ee1c0b53d..3967b0f16 100644
--- a/examples/new_material/local_material_damage.cc
+++ b/examples/new_material/local_material_damage.cc
@@ -1,106 +1,105 @@
/**
* @file local_material_damage.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Nov 26 2010
- * @date last modification: Tue Jun 24 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief Specialization of the material class for the damage material
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "local_material_damage.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
LocalMaterialDamage::LocalMaterialDamage(SolidMechanicsModel & model,
const ID & id) :
Material(model, id),
damage("damage", *this) {
AKANTU_DEBUG_IN();
this->registerParam("E" , E , 0. , _pat_parsable, "Young's modulus" );
this->registerParam("nu" , nu , 0.5 , _pat_parsable, "Poisson's ratio" );
this->registerParam("lambda" , lambda , _pat_readable, "First Lamé coefficient" );
this->registerParam("mu" , mu , _pat_readable, "Second Lamé coefficient");
this->registerParam("kapa" , kpa , _pat_readable, "Bulk coefficient" );
this->registerParam("Yd" , Yd , 50., _pat_parsmod);
this->registerParam("Sd" , Sd , 5000., _pat_parsmod);
damage.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void LocalMaterialDamage::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
lambda = nu * E / ((1 + nu) * (1 - 2*nu));
mu = E / (2 * (1 + nu));
kpa = lambda + 2./3. * mu;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void LocalMaterialDamage::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = damage(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeStressOnQuad(grad_u, sigma, *dam);
++dam;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void LocalMaterialDamage::computePotentialEnergy(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Material::computePotentialEnergy(el_type, ghost_type);
if(ghost_type != _not_ghost) return;
Real * epot = potential_energy(el_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computePotentialEnergyOnQuad(grad_u, sigma, *epot);
epot++;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/examples/new_material/local_material_damage.hh b/examples/new_material/local_material_damage.hh
index 06d28dea7..44a0836f7 100644
--- a/examples/new_material/local_material_damage.hh
+++ b/examples/new_material/local_material_damage.hh
@@ -1,128 +1,127 @@
/**
* @file local_material_damage.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Nov 26 2010
- * @date last modification: Fri May 16 2014
+ * @date creation: Mon Aug 10 2015
*
* @brief Material isotropic elastic
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__
#define __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__
__BEGIN_AKANTU__
class LocalMaterialDamage : public Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
LocalMaterialDamage(SolidMechanicsModel & model, const ID & id = "");
virtual ~LocalMaterialDamage() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void initMaterial();
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// constitutive law for a given quadrature point
inline void computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & damage);
/// compute tangent stiffness
virtual void computeTangentStiffness(__attribute__ ((unused)) const ElementType & el_type,
__attribute__ ((unused)) Array<Real> & tangent_matrix,
__attribute__ ((unused)) GhostType ghost_type = _not_ghost) {};
/// compute the potential energy for all elements
void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost);
/// compute the potential energy for on element
inline void computePotentialEnergyOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & epot);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// compute the celerity of the fastest wave in the material
inline Real getCelerity(const Element & element) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real);
private:
/// the young modulus
Real E;
/// Poisson coefficient
Real nu;
/// First Lamé coefficient
Real lambda;
/// Second Lamé coefficient (shear modulus)
Real mu;
/// resistance to damage
Real Yd;
/// damage threshold
Real Sd;
/// Bulk modulus
Real kpa;
/// damage internal variable
InternalField<Real> damage;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "local_material_damage_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__ */
diff --git a/examples/new_material/local_material_damage_inline_impl.cc b/examples/new_material/local_material_damage_inline_impl.cc
index 3bddbbd03..f380a5e78 100644
--- a/examples/new_material/local_material_damage_inline_impl.cc
+++ b/examples/new_material/local_material_damage_inline_impl.cc
@@ -1,81 +1,80 @@
/**
* @file local_material_damage_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Nov 26 2010
- * @date last modification: Fri May 16 2014
+ * @date creation: Mon Aug 10 2015
*
* @brief Implementation of the inline functions of the material damage
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
inline void LocalMaterialDamage::computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & dam) {
Real trace = grad_u.trace();
/// \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla u_{ij} + \nabla u_{ji})
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
sigma(i, j) = (i == j)*lambda*trace + mu*(grad_u(i, j) + grad_u(j, i));
}
}
Real Y = 0;
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
Y += sigma(i,j) * grad_u(i,j);
}
}
Y *= 0.5;
Real Fd = Y - Yd - Sd*dam;
if (Fd > 0) dam = (Y - Yd) / Sd;
dam = std::min(dam,1.);
sigma *= 1-dam;
}
/* -------------------------------------------------------------------------- */
inline void LocalMaterialDamage::computePotentialEnergyOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & epot) {
epot = 0.;
for (UInt i = 0, t = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j, ++t)
epot += sigma(i, j) * (grad_u(i, j) - (i == j));
epot *= .5;
}
/* -------------------------------------------------------------------------- */
inline Real LocalMaterialDamage::getCelerity(__attribute__ ((unused)) const Element & element) const {
// Here the fastest celerity is the push wave speed
return (std::sqrt((2*mu+lambda)/rho));
}
diff --git a/examples/new_material/new_local_material.cc b/examples/new_material/new_local_material.cc
index 9b9bebf22..ae76cf2f4 100644
--- a/examples/new_material/new_local_material.cc
+++ b/examples/new_material/new_local_material.cc
@@ -1,109 +1,108 @@
/**
* @file new_local_material.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Apr 20 2012
- * @date last modification: Mon Apr 07 2014
+ * @date creation: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "local_material_damage.hh"
using namespace akantu;
#define bar_length 10.
#define bar_height 4.
akantu::Real eps = 1e-10;
int main(int argc, char *argv[]) {
akantu::initialize("material.dat", argc, argv);
UInt max_steps = 10000;
Real epot, ekin;
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("barre_trou.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
/// model creation
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass, true));
model.registerNewCustomMaterials<LocalMaterialDamage>("local_damage");
model.initMaterials();
std::cout << model.getMaterial(0) << std::endl;
Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step/10.);
/// Dirichlet boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y");
// Neumann boundary condition
Matrix<Real> stress(2,2);
stress.eye(3e2);
model.applyBC(BC::Neumann::FromStress(stress), "Traction");
model.setBaseName("local_material");
model.addDumpField("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("grad_u" );
model.addDumpField("stress" );
model.addDumpField("damage" );
model.dump();
for(UInt s = 0; s < max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
if(s % 100 == 0) std::cout << s << " " << epot << " " << ekin << " " << epot + ekin
<< std::endl;
if(s % 100 == 0) model.dump();
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/optimization/CMakeLists.txt b/examples/optimization/CMakeLists.txt
index 49241bdcf..5afced9b0 100644
--- a/examples/optimization/CMakeLists.txt
+++ b/examples/optimization/CMakeLists.txt
@@ -1,32 +1,32 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
#
-# @date Mon Mar 24 11:30:00 2014
+# @date creation: Sun Oct 19 2014
#
# @brief configuration file for contact examples
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
register_example(fn_optimize fn_optimize.cc)
diff --git a/examples/optimization/fn_optimize.cc b/examples/optimization/fn_optimize.cc
index 3855de530..aaa64565f 100644
--- a/examples/optimization/fn_optimize.cc
+++ b/examples/optimization/fn_optimize.cc
@@ -1,101 +1,101 @@
/**
* @file fn_optimize.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date Thu May 22 14:12:00 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief File used to show how to use the NLopt optimizator to find the
* minimum of a function
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <vector>
#include <math.h>
#include "aka_optimize.hh"
typedef struct {
double a, b;
} my_constraint_data;
//! Functor used for the evaluation of the function and its gradient
class Functor {
int count_; //!< Function evaluation counter
public:
//! Default constructor
Functor() : count_() {}
//! Return function evaluation counter
int count() const
{ return count_; }
double operator()(const std::vector<double> &x, std::vector<double> &grad)
{
++count_;
if (!grad.empty()) {
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
return sqrt(x[1]);
}
static double wrap(const std::vector<double> &x, std::vector<double> &grad, void *data) {
return (*reinterpret_cast<Functor*>(data))(x, grad); }
};
double myvconstraint(const std::vector<double> &x, std::vector<double> &grad, void *data)
{
my_constraint_data *d = reinterpret_cast<my_constraint_data*>(data);
double a = d->a, b = d->b;
if (!grad.empty()) {
grad[0] = 3 * a * (a*x[0] + b) * (a*x[0] + b);
grad[1] = -1.0;
}
return ((a*x[0] + b) * (a*x[0] + b) * (a*x[0] + b) - x[1]);
}
int main(int argc, char *argv[]) {
my_constraint_data data[2] = { {2,0}, {-1,1} };
std::vector<double> x(2);
x[0] = 1.234; x[1] = 5.678;
Functor fn;
akantu::Optimizator ofn(x, fn);
ofn.add_inequality_constraint(myvconstraint, &data[0], 1e-8);
ofn.add_inequality_constraint(myvconstraint, &data[1], 1e-8);
ofn.result();
std::cout<<"\nTotal function evaluations: "<<fn.count()<<std::endl;
return 0;
}
diff --git a/examples/parallel_2d/CMakeLists.txt b/examples/parallel_2d/CMakeLists.txt
index 71460593a..90f116c15 100644
--- a/examples/parallel_2d/CMakeLists.txt
+++ b/examples/parallel_2d/CMakeLists.txt
@@ -1,43 +1,42 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Fri Oct 22 2010
-# @date last modification: Thu Nov 01 2012
+# @date creation: Sun Oct 19 2014
#
# @brief configuration for a parallel example
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
#===============================================================================
add_mesh(parallel_2d_mesh square_2d.geo 2 1)
register_example(parallel_2d
parallel_2d.cc)
add_dependencies(parallel_2d
parallel_2d_mesh)
#===============================================================================
file(COPY material.dat DESTINATION .)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
\ No newline at end of file
diff --git a/examples/parallel_2d/parallel_2d.cc b/examples/parallel_2d/parallel_2d.cc
index 592196195..106f703b2 100644
--- a/examples/parallel_2d/parallel_2d.cc
+++ b/examples/parallel_2d/parallel_2d.cc
@@ -1,125 +1,124 @@
/**
* @file parallel_2d.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Oct 22 2010
- * @date last modification: Tue Jun 24 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief Parallel example
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "mesh_io.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[])
{
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblError);
UInt spatial_dimension = 2;
UInt max_steps = 10000;
Real time_factor = 0.8;
Real max_disp = 1e-6;
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
if(prank == 0) {
// Read the mesh
mesh.read("square_2d.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
SolidMechanicsModel model(mesh);
/// model initialization
model.initParallel(partition);
delete partition;
model.initFull();
if(prank == 0) std::cout << model.getMaterial(0) << std::endl;
model.setBaseName("multi");
model.addDumpFieldVector("displacement");
model.addDumpFieldVector("velocity");
model.addDumpFieldVector("acceleration");
model.addDumpFieldTensor("stress");
model.addDumpFieldTensor("grad_u");
/// boundary conditions
Real eps = 1e-16;
const Array<Real> & pos = mesh.getNodes();
Array<Real> & disp = model.getDisplacement();
Array<bool> & boun = model.getBlockedDOFs();
mesh.computeBoundingBox();
Real left_side = mesh.getLowerBounds()(0);
Real right_side = mesh.getUpperBounds()(0);
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
if(std::abs(pos(i,0) - left_side) < eps) {
disp(i, 0) = max_disp;
boun(i, 0) = true;
}
if(std::abs(pos(i,0) - right_side) < eps) {
disp(i, 0) = -max_disp;
boun(i, 0) = true;
}
}
Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
model.dump();
for(UInt s = 1; s <= max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
if(s % 200 == 0) model.dump();
if(prank == 0 && s % 100 == 0)
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/static/CMakeLists.txt b/examples/static/CMakeLists.txt
index 5f1c6bf35..f0518550f 100644
--- a/examples/static/CMakeLists.txt
+++ b/examples/static/CMakeLists.txt
@@ -1,44 +1,43 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Fri Jun 13 2014
-# @date last modification: Fri Jun 13 2014
+# @date creation: Sun Oct 19 2014
#
# @brief configuration implicit tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
#===============================================================================
register_example(static static.cc)
add_mesh(static_mesh square.geo 2 2)
add_dependencies(static static_mesh)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/material.dat
${CMAKE_CURRENT_BINARY_DIR}/material.dat
COPYONLY
)
diff --git a/examples/static/static.cc b/examples/static/static.cc
index 36999592b..cbe187b05 100644
--- a/examples/static/static.cc
+++ b/examples/static/static.cc
@@ -1,80 +1,79 @@
/**
* @file static.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Feb 24 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief This code refers to the implicit static example from the user manual
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
#define bar_length 0.01
#define bar_height 0.01
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("square.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelOptions(_static));
model.setBaseName("static");
model.addDumpFieldVector("displacement");
model.addDumpField("force" );
model.addDumpField("residual");
model.addDumpField("grad_u" );
/// Dirichlet boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y");
model.applyBC(BC::Dirichlet::FixedValue(0.0001, _y), "Traction");
model.dump();
model.assembleStiffnessMatrix();
model.getStiffnessMatrix().saveMatrix("stiffness.mtx");
bool converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-4, 2);
if(!converged)
AKANTU_DEBUG_ERROR("Did not converged in 1 step");
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/structural_mechanics/CMakeLists.txt b/examples/structural_mechanics/CMakeLists.txt
index 57feda912..dd3d062b9 100644
--- a/examples/structural_mechanics/CMakeLists.txt
+++ b/examples/structural_mechanics/CMakeLists.txt
@@ -1,40 +1,39 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Fabian Barras <fabian.barras@epfl.ch>
#
-# @date creation: Thu Jun 12 2014
-# @date last modification: Thu Jun 12 2014
+# @date creation: Sun Oct 19 2014
#
# @brief configuration for structural mechanics example
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
#===============================================================================
add_mesh(parallel_2d_mesh square_2d.geo 2 1)
register_example(bernoulli_beam_2_exemple
bernoulli_beam_2_exemple.cc)
#===============================================================================
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
\ No newline at end of file
diff --git a/examples/structural_mechanics/bernoulli_beam_2_exemple.cc b/examples/structural_mechanics/bernoulli_beam_2_exemple.cc
index c46275f87..5783885aa 100644
--- a/examples/structural_mechanics/bernoulli_beam_2_exemple.cc
+++ b/examples/structural_mechanics/bernoulli_beam_2_exemple.cc
@@ -1,184 +1,183 @@
/**
* @file bernoulli_beam_2_exemple.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date creation: Thu Jun 12 2014
- * @date last modification: Thu Jun 12 2014
+ * @date creation: Sun Oct 19 2014
*
* @brief Computation of the analytical exemple 1.1 in the TGC vol 6
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "structural_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_2
using namespace akantu;
//Linear load function
static void lin_load(double * position, double * load,
__attribute__ ((unused)) Real * normal, __attribute__ ((unused)) UInt surface_id){
memset(load,0,sizeof(Real)*3);
if (position[0]<=10){
load[1]= -6000;
}
}
int main(int argc, char *argv[]){
initialize(argc, argv);
debug::setDebugLevel(dblWarning);
/* -------------------------------------------------------------------------- */
// Defining the mesh
Mesh beams(2);
UInt nb_nodes=3;
UInt nb_nodes_1=1;
UInt nb_nodes_2=nb_nodes-nb_nodes_1 - 1;
UInt nb_element=nb_nodes-1;
Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
nodes.resize(nb_nodes);
beams.addConnectivityType(_bernoulli_beam_2);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_2));
connectivity.resize(nb_element);
for(UInt i=0; i<nb_nodes; ++i) {
nodes(i,1)=0;
}
for (UInt i = 0; i < nb_nodes_1; ++i) {
nodes(i,0)=10.*i/((Real)nb_nodes_1);
}
nodes(nb_nodes_1,0)=10;
for (UInt i = 0; i < nb_nodes_2; ++i) {
nodes(nb_nodes_1 + i + 1,0)=10+ 8.*(i+1)/((Real)nb_nodes_2);
}
for(UInt i=0; i<nb_element; ++i) {
connectivity(i,0)=i;
connectivity(i,1)=i+1;
}
/* -------------------------------------------------------------------------- */
// Defining the materials
StructuralMechanicsModel model(beams);
StructuralMaterial mat1;
mat1.E=3e10;
mat1.I=0.0025;
mat1.A=0.01;
model.addMaterial(mat1);
StructuralMaterial mat2 ;
mat2.E=3e10;
mat2.I=0.00128;
mat2.A=0.01;
model.addMaterial(mat2);
/* -------------------------------------------------------------------------- */
// Defining the forces
model.initFull();
const Real M = -3600; // Momentum at 3
Array<Real> & forces = model.getForce();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
const Array<Real> & N_M = model.getStress(_bernoulli_beam_2);
Array<UInt> & element_material = model.getElementMaterial(_bernoulli_beam_2);
forces.clear();
displacement.clear();
for (UInt i = 0; i < nb_nodes_2; ++i) {
element_material(i+nb_nodes_1)=1;
}
forces(nb_nodes-1,2) += M;
model.computeForcesFromFunction<_bernoulli_beam_2>(lin_load, _bft_traction);
/* -------------------------------------------------------------------------- */
// Defining the boundary conditions
boundary(0,0) = true;
boundary(0,1) = true;
boundary(0,2) = true;
boundary(nb_nodes_1,1) = true;
boundary(nb_nodes-1,1) = true;
/* -------------------------------------------------------------------------- */
// Solve
Real error;
model.assembleStiffnessMatrix();
UInt count = 0;
model.addDumpFieldVector("displacement");
model.addDumpField("rotation");
model.addDumpFieldVector("force");
model.addDumpField("momentum");
do {
if(count != 0) std::cerr << count << " - " << error << std::endl;
model.updateResidual();
model.solve();
count++;
} while (!model.testConvergenceIncrement(1e-10, error) && count < 10);
std::cerr << count << " - " << error << std::endl;
/* -------------------------------------------------------------------------- */
// Post-Processing
model.computeStresses();
std::cout<< " d1 = " << displacement(nb_nodes_1,2) << std::endl;
std::cout<< " d2 = " << displacement(nb_nodes-1,2) << std::endl;
std::cout<< " M1 = " << N_M(0,1) << std::endl;
std::cout<< " M2 = " << N_M(2*(nb_nodes-2),1) << std::endl;
model.dump();
finalize();
}
diff --git a/packages/blackdynamite.cmake b/packages/blackdynamite.cmake
index b4ef8ee38..bdbf11237 100644
--- a/packages/blackdynamite.cmake
+++ b/packages/blackdynamite.cmake
@@ -1,41 +1,44 @@
#===============================================================================
# @file blackdynamite.cmake
#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Tue Nov 29 15:16:35 2011
+# @date creation: Fri Mar 15 2013
+# @date last modification: Mon Sep 28 2015
#
# @brief package description for BlackDynamite support
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
+
package_declare(BlackDynamite EXTERNAL
DESCRIPTION "Use BlackDynamite library"
SYSTEM OFF third-party/cmake/blackdynamite.cmake
EXTRA_PACKAGE_OPTIONS FOUND BlackDynamite_FOUND)
set(_version master)
package_add_third_party_script_variable(BlackDynamite
BLACKDYNAMITE_VERSION "${_version}")
package_add_third_party_script_variable(BlackDynamite
BLACKDYNAMITE_GIT "git@lsmssrv1.epfl.ch:blackdynamite.git")
package_add_third_party_script_variable(BlackDynamite
BLACKDYNAMITE_ARCHIVE "blackdynamite-${_version}.tar.gz")
diff --git a/packages/blas.cmake b/packages/blas.cmake
index ac1c90bfd..61d73f88e 100644
--- a/packages/blas.cmake
+++ b/packages/blas.cmake
@@ -1,81 +1,82 @@
#===============================================================================
-# @file 90_blas.cmake
+# @file blas.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Fri Oct 19 2012
-# @date last modification: Tue Jun 24 2014
+# @date creation: Tue Oct 16 2012
+# @date last modification: Fri Dec 11 2015
#
# @brief package description for blas support
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(BLAS EXTERNAL
DESCRIPTION "Use BLAS for arithmetic operations"
EXTRA_PACKAGE_OPTIONS LANGUAGE Fortran
SYSTEM ON third-party/cmake/blas.cmake)
package_add_third_party_script_variable(BLAS BLAS_ARCHIVE "http://www.netlib.org/blas/blas-3.5.0.tgz")
package_add_third_party_script_variable(BLAS BLAS_VERSION "3.5.0")
set(_default_blas $ENV{BLA_VENDOR})
if(NOT _default_blas)
set(_default_blas Generic)
endif()
set(AKANTU_USE_BLAS_VENDOR "${_default_blas}" CACHE STRING "Version of blas to use")
mark_as_advanced(AKANTU_USE_BLAS_VENDOR)
set_property(CACHE AKANTU_USE_BLAS_VENDOR PROPERTY STRINGS
Goto
ATLAS
PhiPACK
CXML
DXML
SunPerf
SCSL
SGIMATH
IBMESSL
Intel10_32
Intel10_64lp
Intel10_64lp_seq
Intel
ACML
ACML_MP
ACML_GPU
Apple
NAS
Generic
)
set(ENV{BLA_VENDOR} ${AKANTU_USE_BLAS_VENDOR})
if(BLAS_mkl_core_LIBRARY)
set(AKANTU_USE_BLAS_MKL CACHE INTERNAL "" FORCE)
endif()
package_declare_documentation(BLAS
"This package provides access to a BLAS implementation."
""
"Under Ubuntu (14.04 LTS), the installation can be performed using the following command:"
"\\begin{command}"
" > sudo apt-get install libatlas-base-dev"
"\\end{command}"
)
diff --git a/packages/boost.cmake b/packages/boost.cmake
index a2b62ea41..a9e2e905b 100644
--- a/packages/boost.cmake
+++ b/packages/boost.cmake
@@ -1,49 +1,51 @@
#===============================================================================
# @file boost.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Jan 14 2015
+# @date creation: Fri Sep 03 2010
+# @date last modification: Fri Dec 11 2015
#
# @brief package handling the dependencies to boost
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
set(Boost_NO_BOOST_CMAKE ON CACHE BOOL "" FORCE)
package_declare(Boost EXTERNAL
NOT_OPTIONAL
DESCRIPTION "Package handling boost components"
EXTRA_PACKAGE_OPTIONS PREFIX Boost
)
mark_as_advanced(Boost_DIR)
package_on_enabled_script(Boost
"if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER \"4.8\")
set(_boost_version \${Boost_MAJOR_VERSION}.\${Boost_MINOR_VERSION})
if(AKANTU_CORE_CXX11 AND _boost_version VERSION_LESS 1.58 AND _boost_version VERSION_GREATER 1.53)
add_flags(cxx -DBOOST_SPIRIT_USE_PHOENIX_V3)
else()
remove_flags(cxx -DBOOST_SPIRIT_USE_PHOENIX_V3)
endif()
endif()
")
diff --git a/packages/cgal.cmake b/packages/cgal.cmake
index 0b13d94a6..6012b35bb 100644
--- a/packages/cgal.cmake
+++ b/packages/cgal.cmake
@@ -1,72 +1,73 @@
#===============================================================================
# @file cgal.cmake
#
-# @author Lucas Frérot <lucas.frerot@epfl.ch>
+# @author Lucas Frerot <lucas.frerot@epfl.ch>
+# @author Clement Roux <clement.roux@epfl.ch>
#
# @date creation: Thu Feb 19 2015
-# @date last modification: Mon Mar 2 2015
+# @date last modification: Thu Jan 14 2016
#
# @brief package description for CGAL
#
# @section LICENSE
#
-# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
package_declare(CGAL EXTERNAL
DESCRIPTION "Add CGAL support in akantu"
COMPILE_FLAGS "-frounding-math"
BOOST_COMPONENTS system
)
package_declare_sources(CGAL
geometry/mesh_geom_common.hh
geometry/mesh_geom_abstract.hh
geometry/mesh_geom_factory.hh
geometry/mesh_geom_factory_tmpl.hh
geometry/mesh_abstract_intersector.hh
geometry/mesh_abstract_intersector_tmpl.hh
geometry/mesh_geom_intersector.hh
geometry/mesh_geom_intersector_tmpl.hh
geometry/mesh_segment_intersector.hh
geometry/mesh_segment_intersector_tmpl.hh
geometry/mesh_sphere_intersector.hh
geometry/mesh_sphere_intersector_tmpl.hh
geometry/tree_type_helper.hh
geometry/geom_helper_functions.hh
geometry/aabb_primitives/triangle.hh
geometry/aabb_primitives/line_arc.hh
geometry/aabb_primitives/tetrahedron.hh
geometry/aabb_primitives/aabb_primitive.hh
geometry/aabb_primitives/aabb_primitive.cc
)
package_declare_documentation(CGAL
"This package allows the use of CGAL's geometry algorithms in Akantu. Note that it needs a version of CGAL $\\geq$ 4.5 and needs activation of boost's system component."
""
"CGAL checks with an assertion that the compilation flag \\shellcode{-frounding-math} is activated, which forbids the use of Valgrind on any code compilated with the package."
)
diff --git a/packages/cohesive_element.cmake b/packages/cohesive_element.cmake
index b3b99a8bd..334840d1d 100644
--- a/packages/cohesive_element.cmake
+++ b/packages/cohesive_element.cmake
@@ -1,123 +1,125 @@
#===============================================================================
-# @file 20_cohesive_element.cmake
+# @file cohesive_element.cmake
#
-# @author Marco Vocialta <marco.vocialta@epfl.ch>
+# @author Mauro Corrado <mauro.corrado@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
+# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
# @date creation: Tue Oct 16 2012
-# @date last modification: Tue Sep 02 2014
+# @date last modification: Tue Jan 12 2016
#
# @brief package description for cohesive elements
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(cohesive_element
DESCRIPTION "Use cohesive_element package of Akantu"
DEPENDS lapack)
package_declare_sources(cohesive_element
fe_engine/cohesive_element.cc
fe_engine/cohesive_element.hh
fe_engine/fe_engine_template_cohesive.cc
fe_engine/shape_cohesive.hh
fe_engine/shape_cohesive_inline_impl.cc
mesh_utils/cohesive_element_inserter.cc
mesh_utils/cohesive_element_inserter.hh
model/solid_mechanics/materials/material_cohesive/cohesive_internal_field.hh
model/solid_mechanics/materials/material_cohesive/cohesive_internal_field_tmpl.hh
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.cc
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.hh
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.cc
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.hh
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.cc
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc
model/solid_mechanics/materials/material_cohesive/material_cohesive.cc
model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc
model/solid_mechanics/materials/material_cohesive_includes.hh
model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
)
package_declare_elements(cohesive_element
ELEMENT_TYPES
_cohesive_2d_4
_cohesive_2d_6
_cohesive_1d_2
_cohesive_3d_6
_cohesive_3d_12
_cohesive_3d_8
_cohesive_3d_16
KIND cohesive
GEOMETRICAL_TYPES
_gt_cohesive_2d_4
_gt_cohesive_2d_6
_gt_cohesive_1d_2
_gt_cohesive_3d_6
_gt_cohesive_3d_12
_gt_cohesive_3d_8
_gt_cohesive_3d_16
FE_ENGINE_LISTS
gradient_on_integration_points
interpolate_on_integration_points
compute_normals_on_integration_points
inverse_map
contains
get_shapes_derivatives
)
package_declare_material_infos(cohesive_element
LIST AKANTU_COHESIVE_MATERIAL_LIST
INCLUDE material_cohesive_includes.hh
)
package_declare_documentation_files(cohesive_element
manual-cohesive_elements.tex
manual-cohesive_elements_insertion.tex
manual-cohesive_laws.tex
manual-appendix-materials-cohesive.tex
figures/cohesive2d.pdf
figures/cohesive_exponential.pdf
figures/linear_cohesive_law.pdf
figures/bilinear_cohesive_law.pdf
)
package_declare_documentation(cohesive_element
"This package activates the cohesive elements engine within Akantu."
"It depends on:"
"\\begin{itemize}"
" \\item A fortran compiler."
" \\item An implementation of BLAS/LAPACK."
"\\end{itemize}"
)
diff --git a/packages/contact.cmake b/packages/contact.cmake
index 6d7bd8ec9..7dd4dada1 100644
--- a/packages/contact.cmake
+++ b/packages/contact.cmake
@@ -1,79 +1,80 @@
#===============================================================================
-# @file 20_contact.cmake
+# @file contact.cmake
#
# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Nov 21 2011
-# @date last modification: Mon Sep 15 2014
+# @date last modification: Tue Nov 17 2015
#
# @brief package description for contact
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(contact
DESCRIPTION "Use Contact package of Akantu"
DEPENDS cpparray implicit optimization)
package_declare_sources(contact
#cc files
contact/discretization.cc
contact/element.cc
contact/friction.cc
contact/resolution/resolution_augmented_lagrangian.cc
contact/scheme.cc
contact/search.cc
contact/surface.cc
contact/zone.cc
contact/contact_impl.cc
# include files
contact/contact_common.hh
contact/contact_manager.hh
contact/discretization.hh
contact/element.hh
contact/friction.hh
contact/resolution.hh
contact/resolution/resolution_augmented_lagrangian.hh
contact/scheme.hh
contact/search.hh
contact/surface.hh
contact/zone.hh
contact/contact_impl.hh
)
if(AKANTU_CONTACT)
list(APPEND AKANTU_BOOST_COMPONENTS
chrono
system
)
endif()
package_declare_documentation_files(contact
manual-contact.tex
figures/hertz_3D.png
)
package_declare_documentation(contact
"This package enables the contact mechanics engine for Akantu"
)
\ No newline at end of file
diff --git a/packages/core.cmake b/packages/core.cmake
index 3cb5a046e..911e7ad81 100644
--- a/packages/core.cmake
+++ b/packages/core.cmake
@@ -1,484 +1,485 @@
#===============================================================================
-# @file 00_core.cmake
+# @file core.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Nov 21 2011
-# @date last modification: Fri Sep 19 2014
+# @date last modification: Mon Jan 04 2016
#
# @brief package description for core
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(core NOT_OPTIONAL DESCRIPTION "core package for Akantu")
package_declare_sources(core
common/aka_array.cc
common/aka_array.hh
common/aka_array_tmpl.hh
common/aka_blas_lapack.hh
common/aka_circular_array.hh
common/aka_circular_array_inline_impl.cc
common/aka_common.cc
common/aka_common.hh
common/aka_common_inline_impl.cc
common/aka_csr.hh
common/aka_element_classes_info_inline_impl.cc
common/aka_error.cc
common/aka_error.hh
common/aka_event_handler_manager.hh
common/aka_extern.cc
common/aka_fwd.hh
common/aka_grid_dynamic.hh
common/aka_math.cc
common/aka_math.hh
common/aka_math_tmpl.hh
common/aka_memory.cc
common/aka_memory.hh
common/aka_memory_inline_impl.cc
common/aka_random_generator.hh
common/aka_safe_enum.hh
common/aka_static_memory.cc
common/aka_static_memory.hh
common/aka_static_memory_inline_impl.cc
common/aka_static_memory_tmpl.hh
common/aka_typelist.hh
common/aka_types.hh
common/aka_visitor.hh
common/aka_voigthelper.hh
common/aka_voigthelper.cc
fe_engine/element_class.cc
fe_engine/element_class.hh
fe_engine/element_class_tmpl.hh
fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
fe_engine/element_classes/element_class_point_1_inline_impl.cc
fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
fe_engine/element_classes/element_class_segment_2_inline_impl.cc
fe_engine/element_classes/element_class_segment_3_inline_impl.cc
fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
fe_engine/fe_engine.cc
fe_engine/fe_engine.hh
fe_engine/fe_engine_inline_impl.cc
fe_engine/fe_engine_template.hh
fe_engine/fe_engine_template_tmpl.hh
fe_engine/geometrical_element.cc
fe_engine/integration_element.cc
fe_engine/integrator.hh
fe_engine/integrator_gauss.hh
fe_engine/integrator_gauss_inline_impl.cc
fe_engine/interpolation_element.cc
fe_engine/interpolation_element_tmpl.hh
fe_engine/integration_point.hh
fe_engine/shape_functions.hh
fe_engine/shape_functions_inline_impl.cc
fe_engine/shape_lagrange.cc
fe_engine/shape_lagrange.hh
fe_engine/shape_lagrange_inline_impl.cc
fe_engine/shape_linked.cc
fe_engine/shape_linked.hh
fe_engine/shape_linked_inline_impl.cc
fe_engine/element.hh
io/dumper/dumpable.hh
io/dumper/dumpable.cc
io/dumper/dumpable_dummy.hh
io/dumper/dumpable_inline_impl.hh
io/dumper/dumper_field.hh
io/dumper/dumper_material_padders.hh
io/dumper/dumper_filtered_connectivity.hh
io/dumper/dumper_element_partition.hh
io/mesh_io.cc
io/mesh_io.hh
io/mesh_io/mesh_io_abaqus.cc
io/mesh_io/mesh_io_abaqus.hh
io/mesh_io/mesh_io_diana.cc
io/mesh_io/mesh_io_diana.hh
io/mesh_io/mesh_io_msh.cc
io/mesh_io/mesh_io_msh.hh
io/model_io.cc
io/model_io.hh
io/parser/algebraic_parser.hh
io/parser/input_file_parser.hh
io/parser/parsable.cc
io/parser/parsable.hh
io/parser/parsable_tmpl.hh
io/parser/parser.cc
io/parser/parser_real.cc
io/parser/parser_random.cc
io/parser/parser_types.cc
io/parser/parser_input_files.cc
io/parser/parser.hh
io/parser/parser_tmpl.hh
io/parser/parser_grammar_tmpl.hh
io/parser/cppargparse/cppargparse.hh
io/parser/cppargparse/cppargparse.cc
io/parser/cppargparse/cppargparse_tmpl.hh
mesh/element_group.cc
mesh/element_group.hh
mesh/element_group_inline_impl.cc
mesh/element_type_map.hh
mesh/element_type_map_tmpl.hh
mesh/element_type_map_filter.hh
mesh/group_manager.cc
mesh/group_manager.hh
mesh/group_manager_inline_impl.cc
mesh/mesh.cc
mesh/mesh.hh
mesh/mesh_accessor.hh
mesh/mesh_events.hh
mesh/mesh_filter.hh
mesh/mesh_data.cc
mesh/mesh_data.hh
mesh/mesh_data_tmpl.hh
mesh/mesh_inline_impl.cc
mesh/node_group.cc
mesh/node_group.hh
mesh/node_group_inline_impl.cc
mesh_utils/mesh_partition.cc
mesh_utils/mesh_partition.hh
mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
mesh_utils/mesh_partition/mesh_partition_scotch.hh
mesh_utils/mesh_utils_pbc.cc
mesh_utils/mesh_utils.cc
mesh_utils/mesh_utils.hh
mesh_utils/mesh_utils_inline_impl.cc
mesh_utils/global_ids_updater.hh
mesh_utils/global_ids_updater.cc
mesh_utils/global_ids_updater_inline_impl.cc
model/boundary_condition.hh
model/boundary_condition_functor.hh
model/boundary_condition_functor_inline_impl.cc
model/boundary_condition_tmpl.hh
model/integration_scheme/generalized_trapezoidal.hh
model/integration_scheme/generalized_trapezoidal_inline_impl.cc
model/integration_scheme/integration_scheme_1st_order.hh
model/integration_scheme/integration_scheme_2nd_order.hh
model/integration_scheme/newmark-beta.hh
model/integration_scheme/newmark-beta_inline_impl.cc
model/model.cc
model/model.hh
model/model_inline_impl.cc
model/solid_mechanics/material.cc
model/solid_mechanics/material.hh
model/solid_mechanics/material_inline_impl.cc
model/solid_mechanics/material_selector.hh
model/solid_mechanics/material_selector_tmpl.hh
model/solid_mechanics/materials/internal_field.hh
model/solid_mechanics/materials/internal_field_tmpl.hh
model/solid_mechanics/materials/random_internal_field.hh
model/solid_mechanics/materials/random_internal_field_tmpl.hh
model/solid_mechanics/solid_mechanics_model.cc
model/solid_mechanics/solid_mechanics_model.hh
model/solid_mechanics/solid_mechanics_model_inline_impl.cc
model/solid_mechanics/solid_mechanics_model_mass.cc
model/solid_mechanics/solid_mechanics_model_material.cc
model/solid_mechanics/solid_mechanics_model_tmpl.hh
model/solid_mechanics/solid_mechanics_model_event_handler.hh
model/solid_mechanics/materials/plane_stress_toolbox.hh
model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
model/solid_mechanics/materials/material_core_includes.hh
model/solid_mechanics/materials/material_elastic.cc
model/solid_mechanics/materials/material_elastic.hh
model/solid_mechanics/materials/material_elastic_inline_impl.cc
model/solid_mechanics/materials/material_thermal.cc
model/solid_mechanics/materials/material_thermal.hh
model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
model/solid_mechanics/materials/material_elastic_orthotropic.cc
model/solid_mechanics/materials/material_elastic_orthotropic.hh
model/solid_mechanics/materials/material_damage/material_damage.hh
model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
model/solid_mechanics/materials/material_damage/material_marigo.cc
model/solid_mechanics/materials/material_damage/material_marigo.hh
model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
model/solid_mechanics/materials/material_damage/material_mazars.cc
model/solid_mechanics/materials/material_damage/material_mazars.hh
model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
model/solid_mechanics/materials/material_plastic/material_plastic.cc
model/solid_mechanics/materials/material_plastic/material_plastic.hh
model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
model/common/neighborhood_base.hh
model/common/neighborhood_base.cc
model/common/neighborhood_base_inline_impl.cc
model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
solver/solver.cc
solver/solver.hh
solver/solver_inline_impl.cc
solver/sparse_matrix.cc
solver/sparse_matrix.hh
solver/sparse_matrix_inline_impl.cc
solver/static_solver.hh
solver/static_solver.cc
synchronizer/communication_buffer.hh
synchronizer/communication_buffer_inline_impl.cc
synchronizer/data_accessor.cc
synchronizer/data_accessor.hh
synchronizer/data_accessor_inline_impl.cc
synchronizer/distributed_synchronizer.cc
synchronizer/distributed_synchronizer.hh
synchronizer/distributed_synchronizer_tmpl.hh
synchronizer/dof_synchronizer.cc
synchronizer/dof_synchronizer.hh
synchronizer/dof_synchronizer_inline_impl.cc
synchronizer/filtered_synchronizer.cc
synchronizer/filtered_synchronizer.hh
synchronizer/pbc_synchronizer.cc
synchronizer/pbc_synchronizer.hh
synchronizer/real_static_communicator.hh
synchronizer/static_communicator.cc
synchronizer/static_communicator.hh
synchronizer/static_communicator_dummy.hh
synchronizer/static_communicator_inline_impl.hh
synchronizer/synchronizer.cc
synchronizer/synchronizer.hh
synchronizer/synchronizer_registry.cc
synchronizer/synchronizer_registry.hh
synchronizer/grid_synchronizer.cc
synchronizer/grid_synchronizer.hh
)
package_declare_elements(core
ELEMENT_TYPES
_point_1
_segment_2
_segment_3
_triangle_3
_triangle_6
_quadrangle_4
_quadrangle_8
_tetrahedron_4
_tetrahedron_10
_pentahedron_6
_pentahedron_15
_hexahedron_8
_hexahedron_20
KIND regular
GEOMETRICAL_TYPES
_gt_point
_gt_segment_2
_gt_segment_3
_gt_triangle_3
_gt_triangle_6
_gt_quadrangle_4
_gt_quadrangle_8
_gt_tetrahedron_4
_gt_tetrahedron_10
_gt_hexahedron_8
_gt_hexahedron_20
_gt_pentahedron_6
_gt_pentahedron_15
INTERPOLATION_TYPES
_itp_lagrange_point_1
_itp_lagrange_segment_2
_itp_lagrange_segment_3
_itp_lagrange_triangle_3
_itp_lagrange_triangle_6
_itp_lagrange_quadrangle_4
_itp_serendip_quadrangle_8
_itp_lagrange_tetrahedron_4
_itp_lagrange_tetrahedron_10
_itp_lagrange_hexahedron_8
_itp_serendip_hexahedron_20
_itp_lagrange_pentahedron_6
_itp_lagrange_pentahedron_15
GEOMETRICAL_SHAPES
_gst_point
_gst_triangle
_gst_square
_gst_prism
GAUSS_INTEGRATION_TYPES
_git_point
_git_segment
_git_triangle
_git_tetrahedron
_git_pentahedron
INTERPOLATION_KIND _itk_lagrangian
FE_ENGINE_LISTS
gradient_on_integration_points
interpolate_on_integration_points
interpolate
compute_normals_on_integration_points
inverse_map
contains
compute_shapes
compute_shapes_derivatives
get_shapes_derivatives
)
package_declare_material_infos(core
LIST AKANTU_CORE_MATERIAL_LIST
INCLUDE material_core_includes.hh
)
package_declare_documentation_files(core
manual.sty
manual.cls
manual.tex
manual-macros.sty
manual-titlepages.tex
manual-introduction.tex
manual-gettingstarted.tex
manual-io.tex
manual-feengine.tex
manual-solidmechanicsmodel.tex
manual-constitutive-laws.tex
manual-lumping.tex
manual-elements.tex
manual-appendix-elements.tex
manual-appendix-materials.tex
manual-appendix-packages.tex
manual-backmatter.tex
manual-bibliography.bib
manual-bibliographystyle.bst
figures/bc_and_ic_example.pdf
figures/boundary.pdf
figures/boundary.svg
figures/dirichlet.pdf
figures/dirichlet.svg
figures/doc_wheel.pdf
figures/doc_wheel.svg
figures/dynamic_analysis.png
figures/explicit_dynamic.pdf
figures/explicit_dynamic.svg
figures/static.pdf
figures/static.svg
figures/hooke_law.pdf
figures/hot-point-1.png
figures/hot-point-2.png
figures/implicit_dynamic.pdf
figures/implicit_dynamic.svg
figures/insertion.pdf
figures/interpolate.pdf
figures/interpolate.svg
figures/problemDomain.pdf_tex
figures/problemDomain.pdf
figures/static_analysis.png
figures/stress_strain_el.pdf
figures/tangent.pdf
figures/tangent.svg
figures/vectors.pdf
figures/vectors.svg
figures/stress_strain_neo.pdf
figures/visco_elastic_law.pdf
figures/isotropic_hardening_plasticity.pdf
figures/stress_strain_visco.pdf
figures/elements/hexahedron_8.pdf
figures/elements/hexahedron_8.svg
figures/elements/quadrangle_4.pdf
figures/elements/quadrangle_4.svg
figures/elements/quadrangle_8.pdf
figures/elements/quadrangle_8.svg
figures/elements/segment_2.pdf
figures/elements/segment_2.svg
figures/elements/segment_3.pdf
figures/elements/segment_3.svg
figures/elements/tetrahedron_10.pdf
figures/elements/tetrahedron_10.svg
figures/elements/tetrahedron_4.pdf
figures/elements/tetrahedron_4.svg
figures/elements/triangle_3.pdf
figures/elements/triangle_3.svg
figures/elements/triangle_6.pdf
figures/elements/triangle_6.svg
figures/elements/xtemp.pdf
)
package_declare_documentation(core
"This package is the core engine of \\akantu. It depends on:"
"\\begin{itemize}"
"\\item A C++ compiler (\\href{http://gcc.gnu.org/}{GCC} >= 4, or \\href{https://software.intel.com/en-us/intel-compilers}{Intel})."
"\\item The cross-platform, open-source \\href{http://www.cmake.org/}{CMake} build system."
"\\item The \\href{http://www.boost.org/}{Boost} C++ portable libraries."
"\\item The \\href{http://www.zlib.net/}{zlib} compression library."
"\\end{itemize}"
""
"Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
"\\begin{command}"
" > sudo apt-get install cmake libboost-dev zlib1g-dev g++"
"\\end{command}"
""
"Under Mac OS X the installation requires the following steps:"
"\\begin{itemize}"
"\\item Install Xcode"
"\\item Install the command line tools."
"\\item Install the MacPorts project which allows to automatically"
"download and install opensource packages."
"\\end{itemize}"
"Then the following commands should be typed in a terminal:"
"\\begin{command}"
" > sudo port install cmake gcc48 boost"
"\\end{command}"
)
find_program(READLINK_COMMAND readlink)
find_program(ADDR2LINE_COMMAND addr2line)
find_program(PATCH_COMMAND patch)
mark_as_advanced(READLINK_COMMAND)
mark_as_advanced(ADDR2LINE_COMMAND)
include(CheckFunctionExists)
check_function_exists(clock_gettime _clock_gettime)
include(CheckCXXSymbolExists)
check_cxx_symbol_exists(strdup cstring AKANTU_HAS_STRDUP)
if(NOT _clock_gettime)
set(AKANTU_USE_OBSOLETE_GETTIMEOFDAY ON CACHE INTERNAL "" FORCE)
else()
set(AKANTU_USE_OBSOLETE_GETTIMEOFDAY OFF CACHE INTERNAL "" FORCE)
endif()
diff --git a/packages/core_cxx11.cmake b/packages/core_cxx11.cmake
index 95964b330..3ae8f821e 100644
--- a/packages/core_cxx11.cmake
+++ b/packages/core_cxx11.cmake
@@ -1,67 +1,67 @@
#===============================================================================
-# @file 00_core_cxx11.cmake
+# @file core_cxx11.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon May 06 2013
-# @date last modification: Thu Jul 03 2014
+# @date creation: Tue Feb 26 2013
+# @date last modification: Wed Dec 16 2015
#
# @brief C++11 addition to the core package
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
if(AKANTU_CXX11_FLAGS)
package_declare(core_cxx11 ADVANCED
DESCRIPTION "C++ 11 additions for Akantu core" DEFAULT ON
COMPILE_FLAGS "${AKANTU_CXX11_FLAGS}")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.6")
set(AKANTU_CORE_CXX11 OFF CACHE BOOL "C++ 11 additions for Akantu core - not supported by the selected compiler" FORCE)
endif()
endif()
else()
package_declare(core_cxx11 ADVANCED
DESCRIPTION "C++ 11 additions for Akantu core"
DEFAULT OFF
NOT_OPTIONAL
COMPILE_FLAGS "")
endif()
package_declare_sources(core_cxx11
common/aka_point.hh
common/aka_ball.cc
common/aka_plane.hh
common/aka_polytope.hh
common/aka_ball.hh
common/aka_timer.hh
common/aka_tree.hh
common/aka_bounding_box.hh
common/aka_bounding_box.cc
common/aka_geometry.hh
common/aka_geometry.cc
model/solid_mechanics/solid_mechanics_model_element.hh
)
package_declare_documentation(core_cxx11
"This option activates some features of the C++11 standard. This is usable with GCC>=4.7 or Intel>=13.")
diff --git a/packages/cpparray.cmake b/packages/cpparray.cmake
index c5805141a..256cec82e 100644
--- a/packages/cpparray.cmake
+++ b/packages/cpparray.cmake
@@ -1,64 +1,67 @@
#===============================================================================
-# @file cpp_array.cmake
+# @file cpparray.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Mon Nov 21 18:19:15 2011
+# @date creation: Fri Mar 15 2013
+# @date last modification: Mon Mar 30 2015
#
# @brief package description for cpp_array project
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
+
package_declare(CppArray EXTERNAL
DESCRIPTION "Use cpp-array library"
SYSTEM OFF)
package_use_system(CppArray _use_system)
package_get_option_name(CppArray _option_name)
if(NOT ${_use_system})
if(${_option_name})
if(TARGET cpparray)
return()
endif()
set(CPPARRAY_DIR ${PROJECT_BINARY_DIR}/third-party)
include(ExternalProject)
ExternalProject_Add(cpparray
PREFIX ${CPPARRAY_DIR}
GIT_REPOSITORY https://code.google.com/p/cpp-array.git
CMAKE_ARGS <SOURCE_DIR>/cpp-array
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -Dcpp-array_TESTS:BOOL=OFF -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER} -DCMAKE_Fortran_COMPILER:PATH=${CMAKE_Fortran_COMPILER}
)
set(CPPARRAY_INCLUDE_DIR ${CPPARRAY_DIR}/include CACHE PATH "" FORCE)
package_set_include_dir(CppArray ${CPPARRAY_INCLUDE_DIR})
package_add_extra_dependency(CppArray cpparray)
endif()
endif()
package_declare_documentation(CppArray
"This package provides access to the \\href{https://code.google.com/p/cpp-array/}{cpp-array}"
"open-source project. If internet is accessible when configuring the project (during cmake call)"
"this package will be auto-downloaded."
)
diff --git a/packages/damage_non_local.cmake b/packages/damage_non_local.cmake
index d58ff002c..3810c462e 100644
--- a/packages/damage_non_local.cmake
+++ b/packages/damage_non_local.cmake
@@ -1,81 +1,82 @@
#===============================================================================
-# @file 25_damage_non_local.cmake
+# @file damage_non_local.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Fri Jun 15 2012
-# @date last modification: Fri Jun 13 2014
+# @date last modification: Thu Oct 15 2015
#
# @brief package description for non-local materials
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(damage_non_local
DESCRIPTION "Package for Non-local damage constitutives laws Akantu"
DEPENDS lapack)
package_declare_sources(damage_non_local
model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
model/solid_mechanics/materials/material_damage/material_marigo_non_local_inline_impl.cc
model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
model/solid_mechanics/materials/material_non_local.hh
model/solid_mechanics/materials/material_non_local_includes.hh
model/solid_mechanics/materials/material_non_local_inline_impl.cc
model/solid_mechanics/materials/material_non_local.cc
model/solid_mechanics/materials/weight_functions/base_weight_function.hh
model/solid_mechanics/materials/weight_functions/base_weight_function_inline_impl.cc
model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc
model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
model/common/non_local_toolbox/non_local_manager.hh
model/common/non_local_toolbox/non_local_manager.cc
model/common/non_local_toolbox/non_local_manager_inline_impl.cc
model/common/non_local_toolbox/non_local_neighborhood_base.hh
model/common/non_local_toolbox/non_local_neighborhood_base.cc
model/common/non_local_toolbox/non_local_neighborhood.hh
model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
)
package_declare_material_infos(damage_non_local
LIST AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST
INCLUDE material_non_local_includes.hh
)
package_declare_documentation_files(damage_non_local
manual-constitutive-laws-non_local.tex
manual-appendix-materials-non-local.tex)
package_declare_documentation(damage_non_local
"This package activates the non local damage feature of AKANTU"
"")
diff --git a/packages/documentation_doxygen.cmake b/packages/documentation_doxygen.cmake
index 2ba19d387..4af1f52ff 100644
--- a/packages/documentation_doxygen.cmake
+++ b/packages/documentation_doxygen.cmake
@@ -1,47 +1,48 @@
#===============================================================================
-# @file 00_documentation_doxygen.cmake
+# @file documentation_doxygen.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Tue Jun 10 2014
-# @date last modification: Tue Jun 24 2014
+# @date creation: Wed Jun 11 2014
+# @date last modification: Mon Mar 30 2015
#
# @brief Doxygen documentation of the code
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
package_declare(documentation_doxygen
DESCRIPTION "Build source documentation using Doxygen.")
package_declare_documentation(documentation_doxygen
"This generates the Doxygen documantation of the source code."
"It depends on:"
"\\begin{itemize}"
"\\item \\href{http://www.stack.nl/~dimitri/doxygen/}{Doxygen} an automated source code documentations system."
"\\item Optional: \\href{http://www.graphviz.org/}{Graphviz} to generate the dependencies graph"
"\\end{itemize}"
""
"Under Ubuntu (14.04 LTS), the installation of the dependencies can be performed using the following command:"
"\\begin{command}"
" > sudo apt-get install doxygen"
" > sudo apt-get install graphviz"
"\\end{command}"
)
\ No newline at end of file
diff --git a/packages/documentation_manual.cmake b/packages/documentation_manual.cmake
index a649049a7..8d3914cb1 100644
--- a/packages/documentation_manual.cmake
+++ b/packages/documentation_manual.cmake
@@ -1,40 +1,40 @@
#===============================================================================
-# @file 00_documentation_manual.cmake
+# @file documentation_manual.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Tue Jun 10 2014
-# @date last modification: Thu Jul 03 2014
+# @date last modification: Mon Mar 30 2015
#
# @brief Akantu's manual package
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
package_declare(documentation_manual
DESCRIPTION "Build the user manual.")
package_declare_documentation(documentation_manual
"This package alows to compile the user manual in the build folder \\shellcode{build/doc/manual/manual.pdf}."
""
"Under Ubuntu (14.04 LTS), the installation of the dependencies can be performed using the following command:"
"\\begin{command}"
" > sudo apt-get install install rubber texlive texlive-science texlive-latex-extra"
"\\end{command}")
\ No newline at end of file
diff --git a/packages/embedded.cmake b/packages/embedded.cmake
index 920125ff1..0b94ef65d 100644
--- a/packages/embedded.cmake
+++ b/packages/embedded.cmake
@@ -1,56 +1,58 @@
#===============================================================================
# @file embedded.cmake
#
-# @author Lucas Frérot <lucas.frerot@epfl.ch>
+# @author Lucas Frerot <lucas.frerot@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Tue Oct 16 2012
-# @date last modification: Thu Jun 12 2014
+# @date last modification: Mon Dec 14 2015
#
# @brief package descrition for embedded model use
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(embedded
DESCRIPTION "Add support for the embedded solid mechanics model"
DEPENDS CGAL)
package_declare_sources(embedded
model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
model/solid_mechanics/materials/material_embedded/embedded_internal_field.hh
model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
model/solid_mechanics/materials/material_embedded/material_reinforcement.cc
model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
model/solid_mechanics/materials/material_embedded/material_reinforcement_inline_impl.cc
model/solid_mechanics/materials/material_embedded/material_reinforcement_template.hh
model/solid_mechanics/materials/material_embedded/material_reinforcement_template_tmpl.hh
)
package_declare_material_infos(embedded
LIST AKANTU_EMBEDDED_MATERIAL_LIST
INCLUDE material_embedded_includes.hh
)
package_declare_documentation(embedded
"This package allows the use of the embedded model in solid mechanics. This package depends on the CGAL package."
)
diff --git a/packages/heat_transfer.cmake b/packages/heat_transfer.cmake
index 4961e2a2a..506e7a536 100644
--- a/packages/heat_transfer.cmake
+++ b/packages/heat_transfer.cmake
@@ -1,47 +1,49 @@
#===============================================================================
-# @file 10_heat_transfer.cmake
+# @file heat_transfer.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Nov 21 2011
-# @date last modification: Thu Jun 12 2014
+# @date last modification: Mon Mar 30 2015
#
# @brief package description for heat transfer
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(heat_transfer
DESCRIPTION "Use Heat Transfer package of Akantu")
package_declare_sources(heat_transfer
model/heat_transfer/heat_transfer_model.cc
model/heat_transfer/heat_transfer_model.hh
model/heat_transfer/heat_transfer_model_inline_impl.cc
)
package_declare_documentation_files(heat_transfer
manual-heattransfermodel.tex
)
package_declare_documentation(heat_transfer
"This package activates the heat transfer model within Akantu. "
"It has no additional dependencies."
)
\ No newline at end of file
diff --git a/packages/implicit.cmake b/packages/implicit.cmake
index 30211029c..981714fa4 100644
--- a/packages/implicit.cmake
+++ b/packages/implicit.cmake
@@ -1,43 +1,44 @@
#===============================================================================
-# @file 50_implicit.cmake
+# @file implicit.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Tue Oct 16 2012
-# @date last modification: Thu Jun 12 2014
+# @date last modification: Fri Aug 21 2015
#
# @brief package description for the implicit solver
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(implicit META
DESCRIPTION "Add support for implicit time scheme"
DEPENDS scotch mumps)
package_declare_documentation(implicit
"This package activates the sparse solver necessary to solve implicitely static/dynamic"
"finite element problems."
"It depends on:"
"\\begin{itemize}"
" \\item \\href{http://mumps.enseeiht.fr/}{MUMPS}, a parallel sparse direct solver."
" \\item \\href{http://www.labri.fr/perso/pelegrin/scotch/}{Scotch}, a graph partitioner."
"\\end{itemize}"
)
\ No newline at end of file
diff --git a/packages/iohelper.cmake b/packages/iohelper.cmake
index 62e0b7248..5f1f3dceb 100644
--- a/packages/iohelper.cmake
+++ b/packages/iohelper.cmake
@@ -1,69 +1,70 @@
#===============================================================================
-# @file 90_iohelper.cmake
+# @file iohelper.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Tue Nov 29 2011
-# @date last modification: Tue Sep 02 2014
+# @date last modification: Thu Sep 17 2015
#
# @brief package description for iohelper
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(IOHelper EXTERNAL
DESCRIPTION "Add IOHelper support in akantu"
SYSTEM OFF third-party/cmake/iohelper.cmake
DEFAULT ON)
set(_version "master")
package_add_third_party_script_variable(IOHelper
IOHELPER_VERSION ${_version})
package_add_third_party_script_variable(IOHelper
IOHELPER_GIT "https://git.epfl.ch/repo/iohelper.git")
package_add_third_party_script_variable(Scotch
IOHELPER_ARCHIVE "iohelper_${_version}.tar.gz")
package_declare_sources(IOHelper
io/dumper/dumpable_iohelper.hh
io/dumper/dumper_iohelper.hh
io/dumper/dumper_iohelper.cc
io/dumper/dumper_paraview.hh
io/dumper/dumper_text.cc
io/dumper/dumper_text.hh
io/dumper/dumper_paraview.cc
io/dumper/dumper_homogenizing_field.hh
io/dumper/dumper_type_traits.hh
io/dumper/dumper_compute.hh
io/dumper/dumper_nodal_field.hh
io/dumper/dumper_quadrature_point_iterator.hh
io/dumper/dumper_variable.hh
io/dumper/dumper_padding_helper.hh
io/dumper/dumper_elemental_field.hh
io/dumper/dumper_element_iterator.hh
io/dumper/dumper_internal_material_field.hh
io/dumper/dumper_generic_elemental_field.hh
io/dumper/dumper_generic_elemental_field_tmpl.hh
)
package_declare_documentation(IOHelper
"This package activates the IOHelper facilities withing Akantu. This is mandatory if you want to be able to output Paraview files"
"as well as any Dumper within Akantu."
)
diff --git a/packages/lapack.cmake b/packages/lapack.cmake
index 41e92649b..3773d89fb 100644
--- a/packages/lapack.cmake
+++ b/packages/lapack.cmake
@@ -1,42 +1,44 @@
#===============================================================================
-# @file 89_lapack.cmake
+# @file lapack.cmake
#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Fri Oct 19 2012
-# @date last modification: Thu Jun 12 2014
+# @date last modification: Mon Mar 30 2015
#
# @brief package description for lapack support
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(LAPACK EXTERNAL
DESCRIPTION "Use LAPACK for arithmetic operations"
EXTRA_PACKAGE_OPTIONS LANGUAGE Fortran)
package_declare_documentation(LAPACK
"This package provides access to a LAPACK implementation."
""
"Under Ubuntu (14.04 LTS), the installation can be performed using the following command:"
"\\begin{command}"
" > sudo apt-get install libatlas-base-dev"
"\\end{command}"
)
diff --git a/packages/mpi.cmake b/packages/mpi.cmake
index 9fcbab90a..fcce5cb4a 100644
--- a/packages/mpi.cmake
+++ b/packages/mpi.cmake
@@ -1,164 +1,166 @@
#===============================================================================
-# @file 80_mpi.cmake
+# @file mpi.cmake
#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Nov 21 2011
-# @date last modification: Sat Jun 14 2014
+# @date last modification: Wed Jan 13 2016
#
# @brief package description for mpi
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(MPI EXTERNAL
DESCRIPTION "Add MPI support in akantu"
EXTRA_PACKAGE_OPTIONS PREFIX MPI_C MPI
DEPENDS scotch)
package_declare_sources(MPI
synchronizer/mpi_type_wrapper.hh
synchronizer/static_communicator_mpi.cc
synchronizer/static_communicator_mpi_inline_impl.hh
synchronizer/static_communicator_mpi.hh
)
function(add_extra_mpi_options)
unset(MPI_ID CACHE)
package_get_include_dir(MPI _include_dir)
foreach(_inc_dir ${_include_dir})
if(EXISTS "${_inc_dir}/mpi.h")
if(NOT MPI_ID)
file(STRINGS "${_inc_dir}/mpi.h" _mpi_version REGEX "#define MPI_(SUB)?VERSION .*")
foreach(_ver ${_mpi_version})
string(REGEX MATCH "MPI_(VERSION|SUBVERSION) *([0-9]+)" _tmp "${_ver}")
set(_mpi_${CMAKE_MATCH_1} ${CMAKE_MATCH_2})
endforeach()
set(MPI_STD_VERSION "${_mpi_VERSION}.${_mpi_SUBVERSION}" CACHE INTERNAL "")
endif()
if(NOT MPI_ID)
# check if openmpi
file(STRINGS "${_inc_dir}/mpi.h" _ompi_version REGEX "#define OMPI_.*_VERSION .*")
if(_ompi_version)
set(MPI_ID "OpenMPI" CACHE INTERNAL "")
foreach(_version ${_ompi_version})
string(REGEX MATCH "OMPI_(.*)_VERSION (.*)" _tmp "${_version}")
if(_tmp)
set(MPI_VERSION_${CMAKE_MATCH_1} ${CMAKE_MATCH_2})
endif()
endforeach()
set(MPI_ID_VERSION "${MPI_VERSION_MAJOR}.${MPI_VERSION_MINOR}.${MPI_VERSION_RELEASE}" CACHE INTERNAL "")
endif()
endif()
if(NOT MPI_ID)
# check if intelmpi
file(STRINGS "${_inc_dir}/mpi.h" _impi_version REGEX "#define I_MPI_VERSION .*")
if(_impi_version)
set(MPI_ID "IntelMPI" CACHE INTERNAL "")
string(REGEX MATCH "I_MPI_VERSION \"(.*)\"" _tmp "${_impi_version}")
if(_tmp)
set(MPI_ID_VERSION "${CMAKE_MATCH_1}" CACHE INTERNAL "")
endif()
endif()
endif()
if(NOT MPI_ID)
# check if mvapich2
file(STRINGS "${_inc_dir}/mpi.h" _mvapich2_version REGEX "#define MVAPICH2_VERSION .*")
if(_mvapich2_version)
set(MPI_ID "MPVAPICH2" CACHE INTERNAL "")
string(REGEX MATCH "MVAPICH2_VERSION \"(.*)\"" _tmp "${_mvapich2_version}")
if(_tmp)
set(MPI_ID_VERSION "${CMAKE_MATCH_1}" CACHE INTERNAL "")
endif()
endif()
endif()
if(NOT MPI_ID)
# check if mpich (mpich as to be checked after all the mpi that derives from it)
file(STRINGS "${_inc_dir}/mpi.h" _mpich_version REGEX "#define MPICH_VERSION .*")
if(_mpich_version)
set(MPI_ID "MPICH" CACHE INTERNAL "")
string(REGEX MATCH "I_MPI_VERSION \"(.*)\"" _tmp "${_mpich_version}")
if(_tmp)
set(MPI_ID_VERSION "${CMAKE_MATCH_1}" CACHE INTERNAL "")
endif()
endif()
endif()
endif()
endforeach()
if(MPI_ID STREQUAL "IntelMPI" OR
MPI_ID STREQUAL "MPICH" OR
MPI_ID STREQUAL "MVAPICH2")
set(_flags "-DMPICH_IGNORE_CXX_SEEK")
elseif(MPI_ID STREQUAL "OpenMPI")
set(_flags "-DOMPI_SKIP_MPICXX")
package_is_activated(core_cxx11 _act)
if(_act)
set( _flags "${_flags} -Wno-literal-suffix")
endif()
endif()
include(FindPackageMessage)
if(MPI_FOUND)
find_package_message(MPI "MPI ID: ${MPI_ID} ${MPI_ID_VERSION} (MPI standard ${MPI_STD_VERSION})" "${MPI_STD_VERSION}")
endif()
set(MPI_EXTRA_COMPILE_FLAGS "${_flags}" CACHE STRING "Extra flags for MPI" FORCE)
mark_as_advanced(MPI_EXTRA_COMPILE_FLAGS)
#package_get_source_files(MPI _srcs _pub _priv)
#list(APPEND _srcs "common/aka_error.cc")
#set_property(SOURCE ${_srcs} PROPERTY COMPILE_FLAGS "${_flags}")
package_set_compile_flags(MPI ${_flags})
endfunction()
package_on_enabled_script(MPI
"
add_extra_mpi_options()
get_cmake_property(_all_vars VARIABLES)
foreach(_var \${_all_vars})
if(_var MATCHES \"^MPI_.*\")
mark_as_advanced(\${_var})
endif()
endforeach()
"
)
package_declare_documentation(MPI
"This is a meta package providing access to MPI."
""
"Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
"\\begin{command}"
" > sudo apt-get install libopenmpi-dev"
"\\end{command}"
""
"Under Mac OS X the installation requires the following steps:"
"\\begin{command}"
" > sudo port install mpich-devel"
"\\end{command}"
)
diff --git a/packages/mumps.cmake b/packages/mumps.cmake
index 7c47c5056..420d9ff17 100644
--- a/packages/mumps.cmake
+++ b/packages/mumps.cmake
@@ -1,82 +1,84 @@
#===============================================================================
-# @file 85_mumps.cmake
+# @file mumps.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Nov 21 2011
-# @date last modification: Mon Sep 15 2014
+# @date last modification: Fri Aug 21 2015
#
# @brief package description for mumps support
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
+
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
)
package_get_option_name(parallel _par_option)
if(${_par_option})
package_set_find_package_extra_options(Mumps ARGS COMPONENTS "parallel")
package_add_third_party_script_variable(Mumps MUMPS_TYPE "par")
else()
package_set_find_package_extra_options(Mumps ARGS COMPONENTS "sequential")
package_add_third_party_script_variable(Mumps MUMPS_TYPE "seq")
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{<akantu source>/third-party}"
)
diff --git a/packages/nlopt.cmake b/packages/nlopt.cmake
index bb397f123..f16da51b2 100644
--- a/packages/nlopt.cmake
+++ b/packages/nlopt.cmake
@@ -1,83 +1,85 @@
#===============================================================================
-# @file 80_nlopt.cmake
+# @file nlopt.cmake
#
# @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: Thu Jun 05 2014
-# @date last modification: Thu Sep 18 2014
+# @date last modification: Mon Mar 30 2015
#
# @brief package for the opitmization library NLopt
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
+
package_declare(nlopt EXTERNAL
DESCRIPTION "Use NLOPT library"
SYSTEM OFF)
package_use_system(nlopt _use_system)
if(NOT ${_use_system})
package_get_option_name(nlopt _option_name)
if(${_option_name})
set(NLOPT_VERSION "2.4.2")
set(NLOPT_ARCHIVE "${PROJECT_SOURCE_DIR}/third-party/nlopt-${NLOPT_VERSION}.tar.gz")
set(NLOPT_ARCHIVE_HASH "MD5=d0b8f139a4acf29b76dbae69ade8ac54")
if(NOT EXISTS ${NLOPT_ARCHIVE})
set(NLOPT_ARCHIVE "http://ab-initio.mit.edu/nlopt/nlopt-${NLOPT_VERSION}.tar.gz")
endif()
string(TOUPPER "${CMAKE_BUILD_TYPE}" _u_build_type)
set(NLOPT_CONFIGURE_COMMAND CXX=${CMAKE_CXX_COMPILER} CXX_FLAGS=${CMAKE_CXX_FLAGS_${_u_build_type}} <SOURCE_DIR>/configure
--prefix=<INSTALL_DIR> --enable-shared --with-cxx --without-threadlocal
--without-guile --without-python --without-octave --without-matlab)
set(NLOPT_DIR ${PROJECT_BINARY_DIR}/third-party)
include(ExternalProject)
ExternalProject_Add(NLopt
PREFIX ${NLOPT_DIR}
URL ${NLOPT_ARCHIVE}
URL_HASH ${NLOPT_ARCHIVE_HASH}
CONFIGURE_COMMAND ${NLOPT_CONFIGURE_COMMAND}
BUILD_COMMAND make
INSTALL_COMMAND make install
)
set_third_party_shared_libirary_name(NLOPT_LIBRARIES nlopt_cxx)
set(NLOPT_INCLUDE_DIR ${NLOPT_DIR}/include CACHE PATH "Include directories for NLopt" FORCE)
mark_as_advanced(NLOPT_INCLUDE_DIR)
package_set_libraries(nlopt ${NLOPT_LIBRARIES})
package_set_include_dir(nlopt ${NLOPT_INCLUDE_DIR})
package_add_extra_dependency(nlopt NLopt)
endif()
else()
package_rm_extra_dependency(nlopt NLopt)
endif()
package_declare_documentation(nlopt
"This package enable the use of the optimization alogorithm library \\href{http://ab-initio.mit.edu/wiki/index.php/NLopt}{NLopt}."
"Since there are no packaging for the common operating system by default \\akantu compiles it as a third-party project. This behavior can be modified with the option \\code{AKANTU\\_USE\\_THIRD\\_PARTY\\_NLOPT}."
""
"If the automated download fails please download \\href{http://ab-initio.mit.edu/nlopt/nlopt-${NLOPT_VERSION}.tar.gz}{nlopt-${NLOPT_VERSION}.tar.gz} and place it in \\shellcode{<akantu source>/third-party} download."
)
diff --git a/packages/numpy.cmake b/packages/numpy.cmake
index 8be2ea82a..ef7412b26 100644
--- a/packages/numpy.cmake
+++ b/packages/numpy.cmake
@@ -1,27 +1,32 @@
-# @file pythonlibs.cmake
+#===============================================================================
+# @file numpy.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Tue Nov 29 2011
+# @date last modification: Mon Nov 16 2015
+#
# @brief package description for the python library
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(Numpy EXTERNAL DESCRIPTION "Akantu's numpy dependance check")
diff --git a/packages/optimization.cmake b/packages/optimization.cmake
index 1f331dbc1..db5d8fc7e 100644
--- a/packages/optimization.cmake
+++ b/packages/optimization.cmake
@@ -1,46 +1,46 @@
#===============================================================================
-# @file 40_optimization.cmake
+# @file optimization.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Fri Jan 04 2013
-# @date last modification: Wed Jul 30 2014
+# @date last modification: Mon Mar 30 2015
#
# @brief Optimization external library interface
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
package_declare(optimization
DESCRIPTION "Use optimization package in Akantu"
DEPENDS nlopt
ADVANCED)
package_declare_sources(optimization
common/aka_optimize.hh
common/aka_optimize.cc
)
package_declare_documentation(optimization
"This activates the optimization routines of Akantu. This is currently needed by the"
"contact detection algorithms."
)
diff --git a/packages/parallel.cmake b/packages/parallel.cmake
index cd5f985a5..a399710c5 100644
--- a/packages/parallel.cmake
+++ b/packages/parallel.cmake
@@ -1,50 +1,51 @@
#===============================================================================
-# @file 50_parallel.cmake
+# @file parallel.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Tue Oct 16 2012
-# @date last modification: Wed Jun 11 2014
+# @date last modification: Fri Jul 10 2015
#
# @brief meta package description for parallelization
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(parallel META
DESCRIPTION "Add parallel support in Akantu"
DEPENDS mpi scotch)
set(AKANTU_PARALLEL_TESTS
test_solid_mechanics_model_bar_traction2d_parallel
test_solid_mechanics_model_segment_parallel
test_solid_mechanics_model_pbc_parallel
test_synchronizer_communication
test_dof_synchronizer
test_dof_synchronizer_communication
test_solid_mechanics_model_reassign_material
)
package_declare_documentation_files(parallel
manual-parallel.tex
)
package_declare_documentation(parallel
"This option activates the parallel features of AKANTU.")
diff --git a/packages/petsc.cmake b/packages/petsc.cmake
index 6e226adf7..2955aa415 100644
--- a/packages/petsc.cmake
+++ b/packages/petsc.cmake
@@ -1,46 +1,47 @@
#===============================================================================
# @file petsc.cmake
#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
-# @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+# @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Mon Nov 21 18:19:15 2011
+# @date creation: Mon Nov 21 2011
+# @date last modification: Fri Jan 15 2016
#
# @brief package description for PETSc support
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(PETSc EXTERNAL
DESCRIPTION "Add PETSc support in akantu"
EXTRA_PACKAGE_OPTIONS ARGS COMPONENTS C
DEPENDS parallel)
package_declare_sources(petsc
solver/petsc_matrix.hh
solver/petsc_matrix.cc
- solver/petsc_matrix_inline_impl.cc
solver/solver_petsc.hh
solver/solver_petsc.cc
solver/petsc_wrapper.hh
)
diff --git a/packages/python_interface.cmake b/packages/python_interface.cmake
index f42968306..15f925fb5 100644
--- a/packages/python_interface.cmake
+++ b/packages/python_interface.cmake
@@ -1,30 +1,34 @@
#===============================================================================
# @file python_interface.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Tue Nov 29 2011
+# @date last modification: Mon Nov 16 2015
+#
# @brief package description for the python interface
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(python_interface
DESCRIPTION "Akantu's python interface"
DEPENDS PythonLibs)
diff --git a/packages/pythonlibs.cmake b/packages/pythonlibs.cmake
index 5b9c22444..f06530af2 100644
--- a/packages/pythonlibs.cmake
+++ b/packages/pythonlibs.cmake
@@ -1,42 +1,48 @@
#===============================================================================
# @file pythonlibs.cmake
#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Nov 16 2015
+#
# @brief package description for the python library
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
+
set(Python_ADDITIONAL_VERSIONS 2.7)
package_declare(PythonLibs EXTERNAL DESCRIPTION "Akantu's python interface"
DEPENDS numpy
EXTRA_PACKAGE_OPTIONS PREFIX PYTHON FOUND PYTHONLIBS_FOUND
)
package_declare_sources(Pythonlibs
python/python_functor.cc
python/python_functor.hh
python/python_functor_inline_impl.cc
model/boundary_condition_python_functor.hh
model/boundary_condition_python_functor.cc
model/solid_mechanics/materials/material_python/material_python.cc
model/solid_mechanics/materials/material_python/material_python.hh
)
diff --git a/packages/qview.cmake b/packages/qview.cmake
index 81a3b4890..f2f423455 100644
--- a/packages/qview.cmake
+++ b/packages/qview.cmake
@@ -1,35 +1,38 @@
#===============================================================================
# @file qview.cmake
#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Tue Nov 29 15:16:35 2011
+# @date creation: Tue Nov 29 2011
+# @date last modification: Mon Mar 30 2015
#
# @brief package description for qview
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(QVIEW EXTERNAL
DESCRIPTION "Add QView support in akantu")
set(AKANTU_QVIEW_DEB_DEPEND
qview-client
)
diff --git a/packages/scalapack.cmake b/packages/scalapack.cmake
index db263c4e5..253277ab5 100644
--- a/packages/scalapack.cmake
+++ b/packages/scalapack.cmake
@@ -1,42 +1,44 @@
#===============================================================================
# @file scalapack.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Nov 21 2011
-# @date last modification: Mon Sep 15 2014
+# @date creation: Fri Oct 19 2012
+# @date last modification: Mon Mar 30 2015
#
# @brief package description for mumps support
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
+
package_declare(ScaLAPACK EXTERNAL
DESCRIPTION "Add ScaLAPACK support in akantu"
SYSTEM OFF third-party/cmake/scalapack.cmake
DEPENDS MPI
)
package_add_third_party_script_variable(ScaLAPACK
SCALAPACK_VERSION "2.0.2")
package_add_third_party_script_variable(ScaLAPACK
SCALAPACK_ARCHIVE "http://www.netlib.org/scalapack/scalapack-${SCALAPACK_VERSION}.tgz")
package_add_third_party_script_variable(ScaLAPACK
SCALAPACK_ARCHIVE_HASH_2.0.2 "MD5=2f75e600a2ba155ed9ce974a1c4b536f")
diff --git a/packages/scotch.cmake b/packages/scotch.cmake
index dad1b0ca6..c70f50cfa 100644
--- a/packages/scotch.cmake
+++ b/packages/scotch.cmake
@@ -1,95 +1,97 @@
#===============================================================================
-# @file 90_scotch.cmake
+# @file scotch.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Nov 21 2011
-# @date last modification: Thu Jul 10 2014
+# @date last modification: Mon Nov 16 2015
#
# @brief package description for scotch
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
+
package_declare(Scotch EXTERNAL
DESCRIPTION "Add Scotch support in akantu"
SYSTEM ON third-party/cmake/scotch.cmake)
package_declare_sources(Scotch
mesh_utils/mesh_partition/mesh_partition_scotch.cc
)
package_add_third_party_script_variable(Scotch
SCOTCH_VERSION "5.1.12b")
package_add_third_party_script_variable(Scotch
SCOTCH_ARCHIVE_HASH "MD5=e13b49be804755470b159d7052764dc0")
package_add_third_party_script_variable(Scotch
SCOTCH_ARCHIVE "scotch_${SCOTCH_VERSION}_esmumps.tar.gz")
package_add_third_party_script_variable(Scotch
SCOTCH_URL "https://gforge.inria.fr/frs/download.php/28978/scotch_${SCOTCH_VERSION}_esmumps.tar.gz")
package_get_option_name(Scotch _opt_name)
package_use_system(Scotch _system)
if(${_opt_name} AND _system)
include(CheckTypeSize)
package_get_include_dir(Scotch _include_dir)
if(_include_dir)
set(CMAKE_EXTRA_INCLUDE_FILES stdio.h scotch.h)
set(CMAKE_REQUIRED_INCLUDES ${_include_dir})
check_type_size("SCOTCH_Num" SCOTCH_NUM)
if(SCOTCH_NUM AND NOT SCOTCH_NUM EQUAL AKANTU_INTEGER_SIZE)
math(EXPR _n "${AKANTU_INTEGER_SIZE} * 8")
message(SEND_ERROR "This version of Scotch cannot be used, it is compiled with the wrong size for SCOTCH_Num."
"Recompile Scotch with the define -DINTSIZE${_n}. The current scotch integer size is ${SCOTCH_NUM}")
endif()
endif()
endif()
package_declare_documentation(Scotch
"This package enables the use the \\href{http://www.labri.fr/perso/pelegrin/scotch/}{Scotch}"
"library in order to perform a graph partitioning leading to the domain"
"decomposition used within \\akantu"
""
"Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
"\\begin{command}"
" > sudo apt-get install libscotch-dev"
"\\end{command}"
""
"If you activate the advanced option AKANTU\\_USE\\_THIRD\\_PARTY\\_SCOTCH"
"the make system of akantu can automatically compile Scotch."
""
"If the automated download fails due to a SSL access not supported by your"
"version of CMake please download the file"
"\\href{${SCOTCH_ARCHIVE}}{scotch\\_${SCOTCH_VERSION}\\_esmumps.tar.gz}"
"and then place it in the directory \\shellcode{<akantu source>/third-party}"
)
# if(SCOTCH_INCLUDE_DIR)
# file(STRINGS ${SCOTCH_INCLUDE_DIR}/scotch.h SCOTCH_INCLUDE_CONTENT)
# string(REGEX MATCH "_cplusplus" _match ${SCOTCH_INCLUDE_CONTENT})
# if(_match)
# set(AKANTU_SCOTCH_NO_EXTERN ON)
# list(APPEND AKANTU_DEFINITIONS AKANTU_SCOTCH_NO_EXTERN)
# else()
# set(AKANTU_SCOTCH_NO_EXTERN OFF)
# endif()
# endif()
diff --git a/packages/structural_mechanics.cmake b/packages/structural_mechanics.cmake
index aa1946fc3..bcf32ff94 100644
--- a/packages/structural_mechanics.cmake
+++ b/packages/structural_mechanics.cmake
@@ -1,75 +1,76 @@
#===============================================================================
-# @file 10_structural_mechanics.cmake
+# @file structural_mechanics.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Nov 21 2011
-# @date last modification: Mon Jul 07 2014
+# @date last modification: Sun Jul 19 2015
#
# @brief package description for structural mechanics
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
package_declare(structural_mechanics
DESCRIPTION "Use Structural mechanics model package of Akantu"
DEPENDS implicit)
package_declare_sources(structural_mechanics
fe_engine/element_class_structural.hh
fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc
fe_engine/fe_engine_template_tmpl_struct.hh
fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
io/mesh_io/mesh_io_msh_struct.cc
io/mesh_io/mesh_io_msh_struct.hh
io/model_io/model_io_ibarras.cc
io/model_io/model_io_ibarras.hh
model/structural_mechanics/structural_mechanics_model.cc
model/structural_mechanics/structural_mechanics_model.hh
model/structural_mechanics/structural_mechanics_model_boundary.cc
model/structural_mechanics/structural_mechanics_model_inline_impl.cc
model/structural_mechanics/structural_mechanics_model_mass.cc
)
package_declare_elements(structural_mechanics
ELEMENT_TYPES
_bernoulli_beam_2
_bernoulli_beam_3
_kirchhoff_shell
KIND structural
INTERPOLATION_TYPES
_itp_bernoulli_beam
_itp_kirchhoff_shell
INTERPOLATION_KIND
_itk_structural
)
package_declare_documentation_files(structural_mechanics
manual-structuralmechanicsmodel.tex
manual-structuralmechanicsmodel-elements.tex
figures/beam_example.pdf
figures/elements/bernoulli_2.pdf
figures/elements/bernoulli_2.svg
)
package_declare_documentation(structural_mechanics
"This package activates the compilation for the Structural Mechanics engine of Akantu"
)
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 30aca6401..db9a9f45e 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -1,243 +1,244 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Wed Jul 9 17:22:12 2014
+# @date creation: Fri Dec 12 2014
+# @date last modification: Wed Jan 13 2016
#
# @brief CMake file for the python wrapping of akantu
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
#===============================================================================
# Configuration
#===============================================================================
package_get_all_definitions(AKANTU_DEFS)
list(REMOVE_ITEM AKANTU_DEFS AKANTU_CORE_CXX11)
#message(${AKANTU_DEFS})
set(AKA_DEFS "")
foreach (def ${AKANTU_DEFS})
list(APPEND AKA_DEFS "-D${def}")
endforeach()
set(AKANTU_SWIG_FLAGS -w309,325,401,317,509,503,383,384 ${AKA_DEFS})
set(AKANTU_SWIG_OUTDIR ${CMAKE_CURRENT_SOURCE_DIR})
set(AKANTU_SWIG_MODULES swig/akantu.i)
#===============================================================================
# Swig wrapper
#===============================================================================
set(SWIG_REQURIED_VERISON 3.0)
find_package(SWIG ${SWIG_REQURIED_VERISON})
mark_as_advanced(SWIG_EXECUTABLE)
package_get_all_include_directories(
AKANTU_LIBRARY_INCLUDE_DIRS
)
package_get_all_external_informations(
AKANTU_EXTERNAL_INCLUDE_DIR
AKANTU_EXTERNAL_LIBRARIES
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/swig
${AKANTU_LIBRARY_INCLUDE_DIRS}
${PROJECT_BINARY_DIR}/src
${AKANTU_EXTERNAL_INCLUDE_DIR}
)
include(CMakeParseArguments)
function(swig_generate_dependencies _module _depedencies)
set(_dependencies_script "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/_swig_generate_dependencies.cmake")
file(WRITE ${_dependencies_script} "
set(_include_directories ${_include_directories})
list(APPEND _include_directories \"./\")
set(_dep)
set(_files_to_process \${_module})
while(_files_to_process)
list(GET _files_to_process 0 _file)
list(REMOVE_AT _files_to_process 0)
file(STRINGS \${_file} _file_content REGEX \"^%include *\\\"(.*)\\\"\")
set(_includes)
foreach(_line \${_file_content})
string(REGEX REPLACE \"^%include *\\\"(.*)\\\"\" \"\\\\1\" _inc \${_line})
if(_inc)
list(APPEND _includes \${_inc})
endif()
endforeach()
foreach(_include \${_includes})
unset(_found)
foreach(_inc_dir \${_include_directories})
if(EXISTS \${_inc_dir}/\${_include})
set(_found \${_inc_dir}/\${_include})
break()
endif()
endforeach()
if(_found)
list(APPEND _files_to_process \${_found})
list(APPEND _dep \${_found})
endif()
endforeach()
endwhile()
get_filename_component(_module_we \"\${_module}\" NAME_WE)
set(_dependencies_file \${CMAKE_CURRENT_BINARY_DIR}\${CMAKE_FILES_DIRECTORY}/_swig_\${_module_we}_depends.cmake)
file(WRITE \"\${_dependencies_file}\"
\"set(_swig_\${_module_we}_depends\")
foreach(_d \${_dep})
file(APPEND \"\${_dependencies_file}\" \"
\${_d}\")
endforeach()
file(APPEND \"\${_dependencies_file}\" \"
)\")
")
get_directory_property(_include_directories INCLUDE_DIRECTORIES)
get_filename_component(_module_absolute "${_module}" ABSOLUTE)
get_filename_component(_module_we "${_module}" NAME_WE)
set(_dependencies_file ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/_swig_${_module_we}_depends.cmake)
if(EXISTS ${_dependencies_file})
include(${_dependencies_file})
else()
execute_process(COMMAND ${CMAKE_COMMAND}
-D_module=${_module_absolute}
-P ${_dependencies_script}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
include(${_dependencies_file})
endif()
add_custom_command(OUTPUT ${_dependencies_file}
COMMAND ${CMAKE_COMMAND}
-D_module=${_module_absolute}
-P ${_dependencies_script}
COMMENT "Scanning dependencies for swig module ${_module_we}"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
MAIN_DEPENDENCY ${_module_absolute}
DEPENDS ${_swig_${_module_we}_depends}
)
set(${_depedencies} ${_dependencies_file} PARENT_SCOPE)
endfunction()
function(swig_generate_wrappers project _wrappers_cpp _wrappers_py)
cmake_parse_arguments(_swig_opt "" "OUTPUT_DIR" "EXTRA_FLAGS" ${ARGN})
if(_swig_opt_OUTPUT_DIR)
set(_output_dir ${_swig_opt_OUTPUT_DIR})
else()
set(_output_dir ${CMAKE_CURRENT_BINARY_DIR})
endif()
set(_swig_wrappers)
get_directory_property(_include_directories INCLUDE_DIRECTORIES)
if(_include_directories)
string(REPLACE ";" ";-I" _swig_include_directories "${_include_directories}")
endif()
foreach(_module ${_swig_opt_UNPARSED_ARGUMENTS})
swig_generate_dependencies(${_module} _module_dependencies)
get_filename_component(_module_absolute "${_module}" ABSOLUTE)
get_filename_component(_module_path "${_module_absolute}" PATH)
get_filename_component(_module_name "${_module}" NAME)
get_filename_component(_module_we "${_module}" NAME_WE)
set(_wrapper "${_output_dir}/${_module_we}_wrapper.cc")
set(_extra_wrapper "${_output_dir}/${_module_we}.py")
set(_extra_wrapper_bin "${CMAKE_CURRENT_BINARY_DIR}/${_module_we}.py")
if(SWIG_FOUND)
set_source_files_properties("${_wrapper}" PROPERTIES GENERATED 1)
set_source_files_properties("${_extra_wrapper}" PROPERTIES GENERATED 1)
set(_dependencies_file ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/_swig_${_module_we}_depends.cmake)
set(_ouput "${_wrapper}" "${_extra_wrapper}")
add_custom_command(
OUTPUT ${_ouput}
COMMAND "${SWIG_EXECUTABLE}"
ARGS -python -c++
${_swig_opt_EXTRA_FLAGS}
-outdir ${_output_dir}
-I${_swig_include_directories} -I${_module_path}
-o "${_wrapper}"
"${_module_absolute}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${_extra_wrapper} ${_extra_wrapper_bin}
# MAIN_DEPENDENCY "${_module_absolute}"
DEPENDS ${_module_dependencies}
COMMENT "Generating swig wrapper ${_module} -> ${_wrapper}"
)
list(APPEND _swig_wrappers ${_wrapper})
list(APPEND _swig_wrappers_py "${_extra_wrapper_bin}")
else()
if(NOT EXISTS ${_wrapper} OR NOT EXISTS "${_extra_wrapper}")
message(FATAL_ERROR "The file ${_wrapper} and/or ${_extra_wrapper} does "
"not exists and they cannot be generated. Install swig ${SWIG_REQURIED_VERISON} "
" in order to generate them. Or get them from a different machine, "
"in order to be able to compile the python interface")
else()
list(APPEND _swig_wrappers "${_wrapper}")
list(APPEND _swig_wrappers_py "${_extra_wrapper_bin}")
endif()
endif()
endforeach()
add_custom_target(${project}_generate_swig_wrappers DEPENDS ${_swig_wrappers})
set(${_wrappers_cpp} ${_swig_wrappers} PARENT_SCOPE)
set(${_wrappers_py} ${_swig_wrappers_py} PARENT_SCOPE)
endfunction()
swig_generate_wrappers(akantu AKANTU_SWIG_WRAPPERS_CPP AKANTU_WRAPPERS_PYTHON
${AKANTU_SWIG_MODULES}
EXTRA_FLAGS ${AKANTU_SWIG_FLAGS})
if(AKANTU_SWIG_WRAPPERS_CPP)
add_library(_akantu MODULE ${AKANTU_SWIG_WRAPPERS_CPP})
target_link_libraries(_akantu akantu)
set_target_properties(_akantu PROPERTIES PREFIX "")
list(APPEND AKANTU_EXPORT_LIST _akantu)
install(TARGETS _akantu
EXPORT ${AKANTU_TARGETS_EXPORT}
LIBRARY DESTINATION lib COMPONENT python NAMELINK_SKIP # for real systems
ARCHIVE DESTINATION lib COMPONENT python
RUNTIME DESTINATION bin COMPONENT python # for windows ...
)
install(FILES ${AKANTU_WRAPPERS_PYTHON}
DESTINATION lib COMPONENT python
)
endif()
diff --git a/python/swig/aka_array.i b/python/swig/aka_array.i
index 3f220cb6d..f223423fc 100644
--- a/python/swig/aka_array.i
+++ b/python/swig/aka_array.i
@@ -1,187 +1,218 @@
+/**
+ * @file aka_array.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Dec 12 2014
+ * @date last modification: Wed Nov 11 2015
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%{
#define SWIG_FILE_WITH_INIT
#include "aka_array.hh"
%}
%include "typemaps.i"
namespace akantu {
%ignore Array::operator=;
%ignore Array::operator[];
%ignore Array::operator();
%ignore Array::set;
%ignore Array::begin;
%ignore Array::end;
%ignore Array::begin_reinterpret;
%ignore Array::end_reinterpret;
};
%include "aka_array.hh"
namespace akantu {
%template(RArray) Array<akantu::Real, true>;
%template(UArray) Array<akantu::UInt, true>;
%template(BArray) Array<bool, true>;
}
%include "numpy.i"
%init %{
import_array();
%}
%inline %{
namespace akantu{
template <typename T>
class ArrayForPython : public Array<T>{
public:
ArrayForPython(T * wrapped_memory,
UInt size = 0,
UInt nb_component = 1,
const ID & id = "")
: Array<T>(0,nb_component,id){
this->values = wrapped_memory;
this->size = size;
};
~ArrayForPython(){
this->values = NULL;
};
void resize(UInt new_size){
AKANTU_DEBUG_ASSERT(this->size == new_size,"cannot resize a temporary vector");
}
};
}
template <typename T> int getPythonDataTypeCode(){ AKANTU_EXCEPTION("undefined type");}
template <> int getPythonDataTypeCode<bool>(){
int data_typecode = NPY_NOTYPE;
size_t s = sizeof(bool);
switch(s) {
case 1: data_typecode = NPY_BOOL; break;
case 2: data_typecode = NPY_UINT16; break;
case 4: data_typecode = NPY_UINT32; break;
case 8: data_typecode = NPY_UINT64; break;
}
return data_typecode;
}
template <> int getPythonDataTypeCode<double>(){return NPY_DOUBLE;}
template <> int getPythonDataTypeCode<long double>(){return NPY_LONGDOUBLE;}
template <> int getPythonDataTypeCode<float>(){return NPY_FLOAT;}
template <> int getPythonDataTypeCode<unsigned long>(){
int data_typecode = NPY_NOTYPE;
size_t s = sizeof(unsigned long);
switch(s) {
case 2: data_typecode = NPY_UINT16; break;
case 4: data_typecode = NPY_UINT32; break;
case 8: data_typecode = NPY_UINT64; break;
}
return data_typecode;
}
template <> int getPythonDataTypeCode<akantu::UInt>(){
int data_typecode = NPY_NOTYPE;
size_t s = sizeof(akantu::UInt);
switch(s) {
case 2: data_typecode = NPY_UINT16; break;
case 4: data_typecode = NPY_UINT32; break;
case 8: data_typecode = NPY_UINT64; break;
}
return data_typecode;
}
template <> int getPythonDataTypeCode<int>(){
int data_typecode = NPY_NOTYPE;
size_t s = sizeof(int);
switch(s) {
case 2: data_typecode = NPY_INT16; break;
case 4: data_typecode = NPY_INT32; break;
case 8: data_typecode = NPY_INT64; break;
}
return data_typecode;
}
int getSizeOfPythonType(int type_num){
switch (type_num){
case NPY_INT16 : return 2;break;
case NPY_UINT16: return 2;break;
case NPY_INT32 : return 4;break;
case NPY_UINT32: return 4;break;
case NPY_INT64 : return 8;break;
case NPY_UINT64: return 8;break;
case NPY_FLOAT: return sizeof(float);break;
case NPY_DOUBLE: return sizeof(double);break;
case NPY_LONGDOUBLE: return sizeof(long double);break;
}
return 0;
}
std::string getPythonTypeName(int type_num){
switch (type_num){
case NPY_INT16 : return "NPY_INT16" ;break;
case NPY_UINT16: return "NPY_UINT16";break;
case NPY_INT32 : return "NPY_INT32" ;break;
case NPY_UINT32: return "NPY_UINT32";break;
case NPY_INT64 : return "NPY_INT64" ;break;
case NPY_UINT64: return "NPY_UINT64";break;
case NPY_FLOAT: return "NPY_FLOAT" ;break;
case NPY_DOUBLE: return "NPY_DOUBLE";break;
case NPY_LONGDOUBLE: return "NPY_LONGDOUBLE";break;
}
return 0;
}
template <typename T> void checkDataType(int type_num){
AKANTU_DEBUG_ASSERT(type_num == getPythonDataTypeCode<T>(),
"incompatible types between numpy and input function: " <<
type_num << " != " << getPythonDataTypeCode<T>() << std::endl <<
getSizeOfPythonType(type_num) << " != " << sizeof(T) <<
std::endl <<
"The numpy array is of type " << getPythonTypeName(type_num));
}
%}
%define %akantu_array_typemaps(DATA_TYPE)
%typemap(out, fragment="NumPy_Fragments") (akantu::Array< DATA_TYPE > &)
{
int data_typecode = getPythonDataTypeCode< DATA_TYPE >();
npy_intp dims[2] = {npy_intp($1->getSize()), npy_intp($1->getNbComponent())};
PyObject* obj = PyArray_SimpleNewFromData(2, dims, data_typecode, $1->storage());
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result, obj);
}
%typemap(in) akantu::Array< DATA_TYPE > &
{
if (!PyArray_Check($input)) {
AKANTU_EXCEPTION("incompatible input which is not a numpy");
}
else {
PyArray_Descr * numpy_type = (PyArray_Descr*)PyArray_DESCR((PyArrayObject*)$input);
int type_num = numpy_type->type_num;
checkDataType< DATA_TYPE >(type_num);
UInt _n = PyArray_NDIM((PyArrayObject*)$input);
if (_n != 2) AKANTU_EXCEPTION("incompatible numpy dimension " << _n);
npy_intp * ndims = PyArray_DIMS((PyArrayObject*)$input);
akantu::UInt sz = ndims[0];
akantu::UInt nb_components = ndims[1];
PyArrayIterObject *iter = (PyArrayIterObject *)PyArray_IterNew($input);
if (iter == NULL) AKANTU_EXCEPTION("Python internal error");
$1 = new akantu::ArrayForPython< DATA_TYPE >((DATA_TYPE*)(iter->dataptr),sz,nb_components,"tmp_array_for_python");
}
}
%enddef
%akantu_array_typemaps(double )
%akantu_array_typemaps(float )
%akantu_array_typemaps(unsigned int)
%akantu_array_typemaps(unsigned long)
%akantu_array_typemaps(int )
%akantu_array_typemaps(bool )
diff --git a/python/swig/aka_common.i b/python/swig/aka_common.i
index 3f457e370..603eaffa5 100644
--- a/python/swig/aka_common.i
+++ b/python/swig/aka_common.i
@@ -1,92 +1,124 @@
+/**
+ * @file aka_common.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Dec 12 2014
+ * @date last modification: Wed Jan 13 2016
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%{
#include "aka_common.hh"
#include "aka_csr.hh"
#include "element.hh"
%}
namespace akantu {
%ignore getStaticParser;
%ignore getUserParser;
%ignore initialize(int & argc, char ** & argv);
%ignore initialize(const std::string & input_file, int & argc, char ** & argv);
extern const Array<UInt> empty_filter;
}
%typemap(in) (int argc, char *argv[]) {
int i = 0;
if (!PyList_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a list");
return NULL;
}
$1 = PyList_Size($input);
$2 = new char *[$1+1];
for (i = 0; i < $1; i++) {
PyObject *s = PyList_GetItem($input,i);
if (!PyString_Check(s)) {
free($2);
PyErr_SetString(PyExc_ValueError, "List items must be strings");
return NULL;
}
$2[i] = PyString_AsString(s);
}
$2[i] = 0;
}
%typemap(freearg) (int argc, char *argv[]) {
%#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 ignored "-Wmaybe-uninitialized"
%# endif
%#endif
delete [] $2;
%#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
}
%inline %{
namespace akantu {
#if defined(AKANTU_USE_MPI)
const int MPI=1;
#else
const int MPI=0;
#endif
void _initializeWithArgv(const std::string & input_file, int argc, char *argv[]) {
initialize(input_file, argc, argv);
}
}
%}
%pythoncode %{
import sys as _aka_sys
def initialize(input_file="", argv=_aka_sys.argv):
if _aka_sys.modules[__name__].MPI == 1:
try:
from mpi4py import MPI
except ImportError:
pass
_initializeWithArgv(input_file, argv)
%}
%include "aka_config.hh"
%include "aka_common.hh"
%include "aka_element_classes_info.hh"
%include "element.hh"
diff --git a/python/swig/aka_csr.i b/python/swig/aka_csr.i
index 9258a10c5..487537828 100644
--- a/python/swig/aka_csr.i
+++ b/python/swig/aka_csr.i
@@ -1,69 +1,100 @@
+/**
+ * @file aka_csr.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Mon Aug 03 2015
+ * @date last modification: Mon Nov 16 2015
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%{
#include "aka_csr.hh"
%}
namespace akantu {
%ignore CSR::begin;
}
%inline %{
namespace akantu {
template <typename T>
class CSRIterator{
public:
CSRIterator(CSR<T> & csr,UInt row) {
this->it = csr.begin(row);
this->end = csr.end(row);
};
~CSRIterator(){
};
T & __next_cpp(){
if (this->it == this->end) AKANTU_SILENT_EXCEPTION("StopIteration");
T & ref = *(this->it);
++this->it;
return ref;
}
private:
typename CSR<T>::iterator it;
typename CSR<T>::iterator end;
};
}
%}
%extend akantu::CSRIterator<akantu::Element>
{
%insert("python") %{
def __iter__(self):
return self
def __next__(self):
try:
return self.__next_cpp()
except Exception as e:
raise StopIteration
def next(self):
return self.__next__()
%}
}
%extend akantu::CSR<akantu::Element>
{
akantu::CSRIterator<akantu::Element> row(akantu::UInt row){
return akantu::CSRIterator<akantu::Element>(*$self,row);
}
}
%include "aka_csr.hh"
namespace akantu {
%template (CSRUInt) CSR<UInt>;
%template (CSRElement) CSR<Element>;
%template (CSRIteratorElement) CSRIterator<Element>;
}
diff --git a/python/swig/akantu.i b/python/swig/akantu.i
index 1272c7c39..a6845b8da 100644
--- a/python/swig/akantu.i
+++ b/python/swig/akantu.i
@@ -1,48 +1,80 @@
+/**
+ * @file akantu.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Dec 12 2014
+ * @date last modification: Mon Nov 23 2015
+ *
+ * @brief Main swig file for akantu' python interface
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%module akantu
%exception {
try {
$action
} catch (akantu::debug::Exception e) {
PyErr_SetString(PyExc_IndexError,e.what());
return NULL;
}
}
%include "stl.i"
#define __attribute__(x)
%ignore akantu::operator <<;
%include "aka_common.i"
%include "aka_csr.i"
%include "aka_array.i"
%define print_self(MY_CLASS)
%extend akantu::MY_CLASS {
std::string __str__() {
std::stringstream sstr;
sstr << *($self);
return sstr.str();
}
}
%enddef
%include "mesh.i"
%include "mesh_utils.i"
%include "model.i"
%include "solid_mechanics_model.i"
#if defined(AKANTU_COHESIVE_ELEMENT)
%include "solid_mechanics_model_cohesive.i"
#endif
#if defined(AKANTU_HEAT_TRANSFER)
%include "heat_transfer_model.i"
#endif
#if defined(AKANTU_STRUCTURAL_MECHANICS)
%include "load_functions.i"
%include "structural_mechanics_model.i"
#endif
diff --git a/python/swig/heat_transfer_model.i b/python/swig/heat_transfer_model.i
index d42cff43e..1984ba719 100644
--- a/python/swig/heat_transfer_model.i
+++ b/python/swig/heat_transfer_model.i
@@ -1,27 +1,56 @@
+/**
+ * @file heat_transfer_model.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ *
+ * @date creation: Wed Jul 15 2015
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%{
#include "heat_transfer_model.hh"
#include "data_accessor.hh"
%}
namespace akantu {
%ignore HeatTransferModel::initFEEngineBoundary;
%ignore HeatTransferModel::initParallel;
%ignore HeatTransferModel::initArrays;
%ignore HeatTransferModel::initMaterials;
%ignore HeatTransferModel::initModel;
%ignore HeatTransferModel::initPBC;
%ignore HeatTransferModel::initSolver;
%ignore HeatTransferModel::initImplicit;
%ignore HeatTransferModel::getNbDataForElements;
%ignore HeatTransferModel::packElementData;
%ignore HeatTransferModel::unpackElementData;
%ignore HeatTransferModel::getNbDataToPack;
%ignore HeatTransferModel::getNbDataToUnpack;
%ignore HeatTransferModel::packData;
%ignore HeatTransferModel::unpackData;
}
%include "heat_transfer_model.hh"
diff --git a/python/swig/load_functions.i b/python/swig/load_functions.i
index 046c3bfe0..aab57e491 100644
--- a/python/swig/load_functions.i
+++ b/python/swig/load_functions.i
@@ -1,14 +1,43 @@
+/**
+ * @file load_functions.i
+ *
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ *
+ * @date creation: Wed Apr 01 2015
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%inline %{
namespace akantu {
static void lin_load(double * position, double * load,
__attribute__ ((unused)) Real * normal,
__attribute__ ((unused)) UInt surface_id) {
memset(load,0,sizeof(Real)*3);
if (position[0]<=10){
load[1]= -6000;
}
}
}
%}
diff --git a/python/swig/mesh.i b/python/swig/mesh.i
index d3064cd94..682df7b71 100644
--- a/python/swig/mesh.i
+++ b/python/swig/mesh.i
@@ -1,138 +1,171 @@
+/**
+ * @file mesh.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Dec 12 2014
+ * @date last modification: Wed Jan 13 2016
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%{
#include "mesh.hh"
#include "node_group.hh"
#include "solid_mechanics_model.hh"
#include "dumpable_inline_impl.hh"
using akantu::IntegrationPoint;
using akantu::Vector;
using akantu::ElementTypeMapArray;
using akantu::MatrixProxy;
using akantu::Matrix;
using akantu::UInt;
using akantu::Real;
using akantu::Array;
using akantu::SolidMechanicsModel;
%}
namespace akantu {
%ignore NewNodesEvent;
%ignore RemovedNodesEvent;
%ignore NewElementsEvent;
%ignore RemovedElementsEvent;
%ignore MeshEventHandler;
%ignore MeshEvent< UInt >;
%ignore MeshEvent< Element >;
%ignore Mesh::extractNodalCoordinatesFromPBCElement;
%ignore Mesh::getGroupDumer;
%ignore Mesh::getFacetLocalConnectivity;
%ignore Mesh::getAllFacetTypes;
}
print_self(Mesh)
%extend akantu::Mesh {
void resizeMesh(UInt nb_nodes, UInt nb_element, const ElementType & type) {
Array<Real> & nodes = const_cast<Array<Real> &>($self->getNodes());
nodes.resize(nb_nodes);
$self->addConnectivityType(type);
Array<UInt> & connectivity = const_cast<Array<UInt> &>($self->getConnectivity(type));
connectivity.resize(nb_element);
}
#if defined(AKANTU_COHESIVE_ELEMENT)
Array<Real> & getCohesiveBarycenter(SpacialDirection dir) {
UInt spatial_dimension = $self->getSpatialDimension();
ElementTypeMapArray<Real> & barycenter =
$self->registerData<Real>("barycenter");
$self->initElementTypeMapArray(barycenter, 1, spatial_dimension, false,
akantu::_ek_cohesive, true);
akantu::ElementType type = *($self->firstType(
spatial_dimension, akantu::_not_ghost, akantu::_ek_cohesive));
Vector<Real> bary(spatial_dimension);
Array<Real> & bary_coh = barycenter(type);
for (UInt i = 0; i < $self->getNbElement(type); ++i) {
bary.clear();
$self->getBarycenter(i, type, bary.storage());
bary_coh(i) = bary(dir);
}
return bary_coh;
}
#endif
}
%extend akantu::GroupManager {
void createGroupsFromStringMeshData(const std::string & dataset_name) {
$self->createGroupsFromMeshData<std::string>(dataset_name);
}
void createGroupsFromUIntMeshData(const std::string & dataset_name) {
$self->createGroupsFromMeshData<akantu::UInt>(dataset_name);
}
}
%extend akantu::NodeGroup {
akantu::Array<akantu::Real> & getGroupedNodes(akantu::Array<akantu::Real, true> & surface_array, Mesh & mesh) {
akantu::Array<akantu::UInt> group_node = $self->getNodes();
akantu::Array<akantu::Real> & full_array = mesh.getNodes();
surface_array.resize(group_node.getSize());
for (UInt i = 0; i < group_node.getSize(); ++i) {
for (UInt cmp = 0; cmp < full_array.getNbComponent(); ++cmp) {
surface_array(i,cmp) = full_array(group_node(i),cmp);
}
}
akantu::Array<akantu::Real> & res(surface_array);
return res;
}
akantu::Array<akantu::Real> & getGroupedArray(akantu::Array<akantu::Real, true> & surface_array, akantu::SolidMechanicsModel & model, int type) {
akantu::Array<akantu::Real> * full_array;
switch (type) {
case 0 : full_array = new akantu::Array<akantu::Real>(model.getDisplacement());
break;
case 1 : full_array = new akantu::Array<akantu::Real>(model.getVelocity());
break;
case 2 : full_array = new akantu::Array<akantu::Real>(model.getForce());
break;
}
akantu::Array<akantu::UInt> group_node = $self->getNodes();
surface_array.resize(group_node.getSize());
for (UInt i = 0; i < group_node.getSize(); ++i) {
for (UInt cmp = 0; cmp < full_array->getNbComponent(); ++cmp) {
surface_array(i,cmp) = (*full_array)(group_node(i),cmp);
}
}
akantu::Array<akantu::Real> & res(surface_array);
return res;
}
}
%include "group_manager.hh"
%include "element_group.hh"
%include "node_group.hh"
%include "dumper_iohelper.hh"
%include "dumpable_iohelper.hh"
%include "mesh.hh"
namespace akantu{
%extend Dumpable {
void addDumpFieldExternalReal(const std::string & field_id,
const Array<Real> & field){
$self->addDumpFieldExternal<Real>(field_id,field);
}
}
}
diff --git a/python/swig/mesh_utils.i b/python/swig/mesh_utils.i
index a20d0590b..7b10ba0d4 100644
--- a/python/swig/mesh_utils.i
+++ b/python/swig/mesh_utils.i
@@ -1,9 +1,40 @@
+/**
+ * @file mesh_utils.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Dec 12 2014
+ * @date last modification: Thu Jul 23 2015
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
namespace akantu {
%ignore MeshPartition::getPartitions;
%ignore MeshPartition::getPartition;
%ignore MeshPartition::getGhostPartitionCSR;
}
%include "mesh_partition.hh"
%include "mesh_utils.hh"
diff --git a/python/swig/model.i b/python/swig/model.i
index 170d177dc..a998589c8 100644
--- a/python/swig/model.i
+++ b/python/swig/model.i
@@ -1,48 +1,80 @@
+/**
+ * @file model.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Dec 12 2014
+ * @date last modification: Wed Nov 11 2015
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%{
#include "boundary_condition_python_functor.hh"
%}
namespace akantu {
%ignore Model::createSynchronizerRegistry;
%ignore Model::createParallelSynch;
%ignore Model::getDOFSynchronizer;
//%ignore Model::getSynchronizerRegistry;
%ignore Model::registerFEEngineObject;
%ignore Model::unregisterFEEngineObject;
%ignore Model::getFEEngineBoundary;
// %ignore Model::getFEEngine;
%ignore Model::getFEEngineClass;
%ignore Model::getFEEngineClassBoundary;
%ignore Model::setParser;
%ignore IntegrationPoint::operator=;
%ignore FEEngine::getNbIntegrationPoints;
%ignore FEEngine::getShapes;
%ignore FEEngine::getShapesDerivatives;
%ignore FEEngine::getIntegrationPoints;
%ignore FEEngine::getIGFEMElementTypes;
%ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,ElementTypeMapArray<Real> &,const ElementTypeMapArray<UInt> *) const;
%ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,ElementTypeMapArray<Real> &) const;
%ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,Array<Real> &,UInt,const ElementType&,const GhostType &,const Array< UInt > &) const;
%ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,Array<Real> &,UInt,const ElementType&,const GhostType &) const;
}
%include "sparse_matrix.hh"
%include "fe_engine.hh"
%rename(FreeBoundaryDirichlet) akantu::BC::Dirichlet::FreeBoundary;
%rename(FreeBoundaryNeumann) akantu::BC::Neumann::FreeBoundary;
%rename(PythonBoundary) akantu::BC::Dirichlet::PythonFunctor;
%include "boundary_condition_functor.hh"
%include "boundary_condition.hh"
%include "boundary_condition_python_functor.hh"
%include "communication_buffer.hh"
%include "data_accessor.hh"
%include "synchronizer.hh"
%include "synchronizer_registry.hh"
%include "model.hh"
diff --git a/python/swig/numpy.i b/python/swig/numpy.i
index f2714cc34..b88e50645 100644
--- a/python/swig/numpy.i
+++ b/python/swig/numpy.i
@@ -1,3085 +1,3114 @@
+/**
+ * @file numpy.i
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Dec 12 2014
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
/* -*- C -*- (not really, but good for syntax highlighting) */
#ifdef SWIGPYTHON
%{
#ifndef SWIG_FILE_WITH_INIT
#define NO_IMPORT_ARRAY
#endif
#include "stdio.h"
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>
%}
/**********************************************************************/
%fragment("NumPy_Backward_Compatibility", "header")
{
%#if NPY_API_VERSION < 0x00000007
%#define NPY_ARRAY_DEFAULT NPY_DEFAULT
%#define NPY_ARRAY_FARRAY NPY_FARRAY
%#define NPY_FORTRANORDER NPY_FORTRAN
%#endif
}
/**********************************************************************/
/* The following code originally appeared in
* enthought/kiva/agg/src/numeric.i written by Eric Jones. It was
* translated from C++ to C by John Hunter. Bill Spotz has modified
* it to fix some minor bugs, upgrade from Numeric to numpy (all
* versions), add some comments and functionality, and convert from
* direct code insertion to SWIG fragments.
*/
%fragment("NumPy_Macros", "header")
{
/* Macros to extract array attributes.
*/
%#if NPY_API_VERSION < 0x00000007
%#define is_array(a) ((a) && PyArray_Check((PyArrayObject*)a))
%#define array_type(a) (int)(PyArray_TYPE((PyArrayObject*)a))
%#define array_numdims(a) (((PyArrayObject*)a)->nd)
%#define array_dimensions(a) (((PyArrayObject*)a)->dimensions)
%#define array_size(a,i) (((PyArrayObject*)a)->dimensions[i])
%#define array_strides(a) (((PyArrayObject*)a)->strides)
%#define array_stride(a,i) (((PyArrayObject*)a)->strides[i])
%#define array_data(a) (((PyArrayObject*)a)->data)
%#define array_descr(a) (((PyArrayObject*)a)->descr)
%#define array_flags(a) (((PyArrayObject*)a)->flags)
%#define array_enableflags(a,f) (((PyArrayObject*)a)->flags) = f
%#else
%#define is_array(a) ((a) && PyArray_Check(a))
%#define array_type(a) PyArray_TYPE((PyArrayObject*)a)
%#define array_numdims(a) PyArray_NDIM((PyArrayObject*)a)
%#define array_dimensions(a) PyArray_DIMS((PyArrayObject*)a)
%#define array_strides(a) PyArray_STRIDES((PyArrayObject*)a)
%#define array_stride(a,i) PyArray_STRIDE((PyArrayObject*)a,i)
%#define array_size(a,i) PyArray_DIM((PyArrayObject*)a,i)
%#define array_data(a) PyArray_DATA((PyArrayObject*)a)
%#define array_descr(a) PyArray_DESCR((PyArrayObject*)a)
%#define array_flags(a) PyArray_FLAGS((PyArrayObject*)a)
%#define array_enableflags(a,f) PyArray_ENABLEFLAGS((PyArrayObject*)a,f)
%#endif
%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS((PyArrayObject*)a))
%#define array_is_native(a) (PyArray_ISNOTSWAPPED((PyArrayObject*)a))
%#define array_is_fortran(a) (PyArray_ISFORTRAN((PyArrayObject*)a))
}
/**********************************************************************/
%fragment("NumPy_Utilities",
"header")
{
/* Given a PyObject, return a string describing its type.
*/
const char* pytype_string(PyObject* py_obj)
{
if (py_obj == NULL ) return "C NULL value";
if (py_obj == Py_None ) return "Python None" ;
if (PyCallable_Check(py_obj)) return "callable" ;
if (PyString_Check( py_obj)) return "string" ;
if (PyInt_Check( py_obj)) return "int" ;
if (PyFloat_Check( py_obj)) return "float" ;
if (PyDict_Check( py_obj)) return "dict" ;
if (PyList_Check( py_obj)) return "list" ;
if (PyTuple_Check( py_obj)) return "tuple" ;
%#if PY_MAJOR_VERSION < 3
if (PyFile_Check( py_obj)) return "file" ;
if (PyModule_Check( py_obj)) return "module" ;
if (PyInstance_Check(py_obj)) return "instance" ;
%#endif
return "unkown type";
}
/* Given a NumPy typecode, return a string describing the type.
*/
const char* typecode_string(int typecode)
{
static const char* type_names[25] = {"bool",
"byte",
"unsigned byte",
"short",
"unsigned short",
"int",
"unsigned int",
"long",
"unsigned long",
"long long",
"unsigned long long",
"float",
"double",
"long double",
"complex float",
"complex double",
"complex long double",
"object",
"string",
"unicode",
"void",
"ntypes",
"notype",
"char",
"unknown"};
return typecode < 24 ? type_names[typecode] : type_names[24];
}
/* Make sure input has correct numpy type. This now just calls
PyArray_EquivTypenums().
*/
int type_match(int actual_type,
int desired_type)
{
return PyArray_EquivTypenums(actual_type, desired_type);
}
%#ifdef SWIGPY_USE_CAPSULE
void free_cap(PyObject * cap)
{
void* array = (void*) PyCapsule_GetPointer(cap,SWIGPY_CAPSULE_NAME);
if (array != NULL) free(array);
}
%#endif
}
/**********************************************************************/
%fragment("NumPy_Object_to_Array",
"header",
fragment="NumPy_Backward_Compatibility",
fragment="NumPy_Macros",
fragment="NumPy_Utilities")
{
/* Given a PyObject pointer, cast it to a PyArrayObject pointer if
* legal. If not, set the python error string appropriately and
* return NULL.
*/
PyArrayObject* obj_to_array_no_conversion(PyObject* input,
int typecode)
{
PyArrayObject* ary = NULL;
if (is_array(input) && (typecode == NPY_NOTYPE ||
PyArray_EquivTypenums(array_type(input), typecode)))
{
ary = (PyArrayObject*) input;
}
else if is_array(input)
{
const char* desired_type = typecode_string(typecode);
const char* actual_type = typecode_string(array_type(input));
PyErr_Format(PyExc_TypeError,
"Array of type '%s' required. Array of type '%s' given",
desired_type, actual_type);
ary = NULL;
}
else
{
const char* desired_type = typecode_string(typecode);
const char* actual_type = pytype_string(input);
PyErr_Format(PyExc_TypeError,
"Array of type '%s' required. A '%s' was given",
desired_type,
actual_type);
ary = NULL;
}
return ary;
}
/* Convert the given PyObject to a NumPy array with the given
* typecode. On success, return a valid PyArrayObject* with the
* correct type. On failure, the python error string will be set and
* the routine returns NULL.
*/
PyArrayObject* obj_to_array_allow_conversion(PyObject* input,
int typecode,
int* is_new_object)
{
PyArrayObject* ary = NULL;
PyObject* py_obj;
if (is_array(input) && (typecode == NPY_NOTYPE ||
PyArray_EquivTypenums(array_type(input),typecode)))
{
ary = (PyArrayObject*) input;
*is_new_object = 0;
}
else
{
py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_ARRAY_DEFAULT);
/* If NULL, PyArray_FromObject will have set python error value.*/
ary = (PyArrayObject*) py_obj;
*is_new_object = 1;
}
return ary;
}
/* Given a PyArrayObject, check to see if it is contiguous. If so,
* return the input pointer and flag it as not a new object. If it is
* not contiguous, create a new PyArrayObject using the original data,
* flag it as a new object and return the pointer.
*/
PyArrayObject* make_contiguous(PyArrayObject* ary,
int* is_new_object,
int min_dims,
int max_dims)
{
PyArrayObject* result;
if (array_is_contiguous(ary))
{
result = ary;
*is_new_object = 0;
}
else
{
result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
array_type(ary),
min_dims,
max_dims);
*is_new_object = 1;
}
return result;
}
/* Given a PyArrayObject, check to see if it is Fortran-contiguous.
* If so, return the input pointer, but do not flag it as not a new
* object. If it is not Fortran-contiguous, create a new
* PyArrayObject using the original data, flag it as a new object
* and return the pointer.
*/
PyArrayObject* make_fortran(PyArrayObject* ary,
int* is_new_object)
{
PyArrayObject* result;
if (array_is_fortran(ary))
{
result = ary;
*is_new_object = 0;
}
else
{
Py_INCREF(array_descr(ary));
result = (PyArrayObject*) PyArray_FromArray(ary,
array_descr(ary),
NPY_FORTRANORDER);
*is_new_object = 1;
}
return result;
}
/* Convert a given PyObject to a contiguous PyArrayObject of the
* specified type. If the input object is not a contiguous
* PyArrayObject, a new one will be created and the new object flag
* will be set.
*/
PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
int typecode,
int* is_new_object)
{
int is_new1 = 0;
int is_new2 = 0;
PyArrayObject* ary2;
PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
typecode,
&is_new1);
if (ary1)
{
ary2 = make_contiguous(ary1, &is_new2, 0, 0);
if ( is_new1 && is_new2)
{
Py_DECREF(ary1);
}
ary1 = ary2;
}
*is_new_object = is_new1 || is_new2;
return ary1;
}
/* Convert a given PyObject to a Fortran-ordered PyArrayObject of the
* specified type. If the input object is not a Fortran-ordered
* PyArrayObject, a new one will be created and the new object flag
* will be set.
*/
PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input,
int typecode,
int* is_new_object)
{
int is_new1 = 0;
int is_new2 = 0;
PyArrayObject* ary2;
PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
typecode,
&is_new1);
if (ary1)
{
ary2 = make_fortran(ary1, &is_new2);
if (is_new1 && is_new2)
{
Py_DECREF(ary1);
}
ary1 = ary2;
}
*is_new_object = is_new1 || is_new2;
return ary1;
}
} /* end fragment */
/**********************************************************************/
%fragment("NumPy_Array_Requirements",
"header",
fragment="NumPy_Backward_Compatibility",
fragment="NumPy_Macros")
{
/* Test whether a python object is contiguous. If array is
* contiguous, return 1. Otherwise, set the python error string and
* return 0.
*/
int require_contiguous(PyArrayObject* ary)
{
int contiguous = 1;
if (!array_is_contiguous(ary))
{
PyErr_SetString(PyExc_TypeError,
"Array must be contiguous. A non-contiguous array was given");
contiguous = 0;
}
return contiguous;
}
/* Require that a numpy array is not byte-swapped. If the array is
* not byte-swapped, return 1. Otherwise, set the python error string
* and return 0.
*/
int require_native(PyArrayObject* ary)
{
int native = 1;
if (!array_is_native(ary))
{
PyErr_SetString(PyExc_TypeError,
"Array must have native byteorder. "
"A byte-swapped array was given");
native = 0;
}
return native;
}
/* Require the given PyArrayObject to have a specified number of
* dimensions. If the array has the specified number of dimensions,
* return 1. Otherwise, set the python error string and return 0.
*/
int require_dimensions(PyArrayObject* ary,
int exact_dimensions)
{
int success = 1;
if (array_numdims(ary) != exact_dimensions)
{
PyErr_Format(PyExc_TypeError,
"Array must have %d dimensions. Given array has %d dimensions",
exact_dimensions,
array_numdims(ary));
success = 0;
}
return success;
}
/* Require the given PyArrayObject to have one of a list of specified
* number of dimensions. If the array has one of the specified number
* of dimensions, return 1. Otherwise, set the python error string
* and return 0.
*/
int require_dimensions_n(PyArrayObject* ary,
int* exact_dimensions,
int n)
{
int success = 0;
int i;
char dims_str[255] = "";
char s[255];
for (i = 0; i < n && !success; i++)
{
if (array_numdims(ary) == exact_dimensions[i])
{
success = 1;
}
}
if (!success)
{
for (i = 0; i < n-1; i++)
{
sprintf(s, "%d, ", exact_dimensions[i]);
strcat(dims_str,s);
}
sprintf(s, " or %d", exact_dimensions[n-1]);
strcat(dims_str,s);
PyErr_Format(PyExc_TypeError,
"Array must have %s dimensions. Given array has %d dimensions",
dims_str,
array_numdims(ary));
}
return success;
}
/* Require the given PyArrayObject to have a specified shape. If the
* array has the specified shape, return 1. Otherwise, set the python
* error string and return 0.
*/
int require_size(PyArrayObject* ary,
npy_intp* size,
int n)
{
int i;
int success = 1;
int len;
char desired_dims[255] = "[";
char s[255];
char actual_dims[255] = "[";
for(i=0; i < n;i++)
{
if (size[i] != -1 && size[i] != array_size(ary,i))
{
success = 0;
}
}
if (!success)
{
for (i = 0; i < n; i++)
{
if (size[i] == -1)
{
sprintf(s, "*,");
}
else
{
sprintf(s, "%ld,", (long int)size[i]);
}
strcat(desired_dims,s);
}
len = strlen(desired_dims);
desired_dims[len-1] = ']';
for (i = 0; i < n; i++)
{
sprintf(s, "%ld,", (long int)array_size(ary,i));
strcat(actual_dims,s);
}
len = strlen(actual_dims);
actual_dims[len-1] = ']';
PyErr_Format(PyExc_TypeError,
"Array must have shape of %s. Given array has shape of %s",
desired_dims,
actual_dims);
}
return success;
}
/* Require the given PyArrayObject to to be Fortran ordered. If the
* the PyArrayObject is already Fortran ordered, do nothing. Else,
* set the Fortran ordering flag and recompute the strides.
*/
int require_fortran(PyArrayObject* ary)
{
int success = 1;
int nd = array_numdims(ary);
int i;
npy_intp * strides = array_strides(ary);
if (array_is_fortran(ary)) return success;
/* Set the Fortran ordered flag */
array_enableflags(ary,NPY_ARRAY_FARRAY);
/* Recompute the strides */
strides[0] = strides[nd-1];
for (i=1; i < nd; ++i)
strides[i] = strides[i-1] * array_size(ary,i-1);
return success;
}
}
/* Combine all NumPy fragments into one for convenience */
%fragment("NumPy_Fragments",
"header",
fragment="NumPy_Backward_Compatibility",
fragment="NumPy_Macros",
fragment="NumPy_Utilities",
fragment="NumPy_Object_to_Array",
fragment="NumPy_Array_Requirements")
{
}
/* End John Hunter translation (with modifications by Bill Spotz)
*/
/* %numpy_typemaps() macro
*
* This macro defines a family of 74 typemaps that allow C arguments
* of the form
*
* 1. (DATA_TYPE IN_ARRAY1[ANY])
* 2. (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
* 3. (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
*
* 4. (DATA_TYPE IN_ARRAY2[ANY][ANY])
* 5. (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
* 6. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
* 7. (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
* 8. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
*
* 9. (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
* 10. (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
* 11. (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
* 12. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
* 13. (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
* 14. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
*
* 15. (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
* 16. (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
* 17. (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
* 18. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
* 19. (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
* 20. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
*
* 21. (DATA_TYPE INPLACE_ARRAY1[ANY])
* 22. (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
* 23. (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
*
* 24. (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
* 25. (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
* 26. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
* 27. (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
* 28. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
*
* 29. (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
* 30. (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
* 31. (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
* 32. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
* 33. (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
* 34. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
*
* 35. (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
* 36. (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
* 37. (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
* 38. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
* 39. (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
* 40. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
*
* 41. (DATA_TYPE ARGOUT_ARRAY1[ANY])
* 42. (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
* 43. (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
*
* 44. (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
*
* 45. (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
*
* 46. (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
*
* 47. (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
* 48. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
*
* 49. (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
* 50. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
* 51. (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
* 52. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
*
* 53. (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
* 54. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
* 55. (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
* 56. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
*
* 57. (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
* 58. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
* 59. (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
* 60. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
*
* 61. (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
* 62. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
*
* 63. (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
* 64. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
* 65. (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
* 66. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
*
* 67. (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
* 68. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
* 69. (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
* 70. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
*
* 71. (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
* 72. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
* 73. (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
* 74. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
*
* where "DATA_TYPE" is any type supported by the NumPy module, and
* "DIM_TYPE" is any int-like type suitable for specifying dimensions.
* The difference between "ARRAY" typemaps and "FARRAY" typemaps is
* that the "FARRAY" typemaps expect Fortran ordering of
* multidimensional arrays. In python, the dimensions will not need
* to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1"
* typemaps). The IN_ARRAYs can be a numpy array or any sequence that
* can be converted to a numpy array of the specified type. The
* INPLACE_ARRAYs must be numpy arrays of the appropriate type. The
* ARGOUT_ARRAYs will be returned as new numpy arrays of the
* appropriate type.
*
* These typemaps can be applied to existing functions using the
* %apply directive. For example:
*
* %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)};
* double prod(double* series, int length);
*
* %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2)
* {(int rows, int cols, double* matrix )};
* void floor(int rows, int cols, double* matrix, double f);
*
* %apply (double IN_ARRAY3[ANY][ANY][ANY])
* {(double tensor[2][2][2] )};
* %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
* {(double low[2][2][2] )};
* %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
* {(double upp[2][2][2] )};
* void luSplit(double tensor[2][2][2],
* double low[2][2][2],
* double upp[2][2][2] );
*
* or directly with
*
* double prod(double* IN_ARRAY1, int DIM1);
*
* void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f);
*
* void luSplit(double IN_ARRAY3[ANY][ANY][ANY],
* double ARGOUT_ARRAY3[ANY][ANY][ANY],
* double ARGOUT_ARRAY3[ANY][ANY][ANY]);
*/
%define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE)
/************************/
/* Input Array Typemaps */
/************************/
/* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY])
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE IN_ARRAY1[ANY])
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE IN_ARRAY1[ANY])
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[1] = { $1_dim0 };
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 1) ||
!require_size(array, size, 1)) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
%typemap(freearg)
(DATA_TYPE IN_ARRAY1[ANY])
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[1] = { -1 };
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 1) ||
!require_size(array, size, 1)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
}
%typemap(freearg)
(DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[1] = {-1};
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 1) ||
!require_size(array, size, 1)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DATA_TYPE*) array_data(array);
}
%typemap(freearg)
(DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY])
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE IN_ARRAY2[ANY][ANY])
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE IN_ARRAY2[ANY][ANY])
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[2] = { $1_dim0, $1_dim1 };
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 2) ||
!require_size(array, size, 2)) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
%typemap(freearg)
(DATA_TYPE IN_ARRAY2[ANY][ANY])
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[2] = { -1, -1 };
array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 2) ||
!require_size(array, size, 2)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
}
%typemap(freearg)
(DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[2] = { -1, -1 };
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 2) ||
!require_size(array, size, 2)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DATA_TYPE*) array_data(array);
}
%typemap(freearg)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[2] = { -1, -1 };
array = obj_to_array_fortran_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 2) ||
!require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
}
%typemap(freearg)
(DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[2] = { -1, -1 };
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 2) ||
!require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DATA_TYPE*) array_data(array);
}
%typemap(freearg)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 3) ||
!require_size(array, size, 3)) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
%typemap(freearg)
(DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[3] = { -1, -1, -1 };
array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 3) ||
!require_size(array, size, 3)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
$4 = (DIM_TYPE) array_size(array,2);
}
%typemap(freearg)
(DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
/* for now, only concerned with lists */
$1 = PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
(DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
{
npy_intp size[2] = { -1, -1 };
PyArrayObject* temp_array;
Py_ssize_t i;
int is_new_object;
/* length of the list */
$2 = PyList_Size($input);
/* the arrays */
array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
is_new_object_array = (int *)calloc($2,sizeof(int));
if (array == NULL || object_array == NULL || is_new_object_array == NULL)
{
SWIG_fail;
}
for (i=0; i<$2; i++)
{
temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
/* the new array must be stored so that it can be destroyed in freearg */
object_array[i] = temp_array;
is_new_object_array[i] = is_new_object;
if (!temp_array || !require_dimensions(temp_array, 2)) SWIG_fail;
/* store the size of the first array in the list, then use that for comparison. */
if (i == 0)
{
size[0] = array_size(temp_array,0);
size[1] = array_size(temp_array,1);
}
if (!require_size(temp_array, size, 2)) SWIG_fail;
array[i] = (DATA_TYPE*) array_data(temp_array);
}
$1 = (DATA_TYPE**) array;
$3 = (DIM_TYPE) size[0];
$4 = (DIM_TYPE) size[1];
}
%typemap(freearg)
(DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
Py_ssize_t i;
if (array$argnum!=NULL) free(array$argnum);
/*freeing the individual arrays if needed */
if (object_array$argnum!=NULL)
{
if (is_new_object_array$argnum!=NULL)
{
for (i=0; i<$2; i++)
{
if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
{ Py_DECREF(object_array$argnum[i]); }
}
free(is_new_object_array$argnum);
}
free(object_array$argnum);
}
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
* DATA_TYPE* IN_ARRAY3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[3] = { -1, -1, -1 };
array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 3) ||
!require_size(array, size, 3)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DIM_TYPE) array_size(array,2);
$4 = (DATA_TYPE*) array_data(array);
}
%typemap(freearg)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[3] = { -1, -1, -1 };
array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 3) ||
!require_size(array, size, 3) | !require_fortran(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
$4 = (DIM_TYPE) array_size(array,2);
}
%typemap(freearg)
(DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
* DATA_TYPE* IN_FARRAY3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[3] = { -1, -1, -1 };
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 3) ||
!require_size(array, size, 3) || !require_fortran(array)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DIM_TYPE) array_size(array,2);
$4 = (DATA_TYPE*) array_data(array);
}
%typemap(freearg)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3};
array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 4) ||
!require_size(array, size, 4)) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
%typemap(freearg)
(DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3, DIM_TYPE DIM4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[4] = { -1, -1, -1, -1 };
array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 4) ||
!require_size(array, size, 4)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
$4 = (DIM_TYPE) array_size(array,2);
$5 = (DIM_TYPE) array_size(array,3);
}
%typemap(freearg)
(DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3, DIM_TYPE DIM4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
/* for now, only concerned with lists */
$1 = PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
{
npy_intp size[3] = { -1, -1, -1 };
PyArrayObject* temp_array;
Py_ssize_t i;
int is_new_object;
/* length of the list */
$2 = PyList_Size($input);
/* the arrays */
array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
is_new_object_array = (int *)calloc($2,sizeof(int));
if (array == NULL || object_array == NULL || is_new_object_array == NULL)
{
SWIG_fail;
}
for (i=0; i<$2; i++)
{
temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
/* the new array must be stored so that it can be destroyed in freearg */
object_array[i] = temp_array;
is_new_object_array[i] = is_new_object;
if (!temp_array || !require_dimensions(temp_array, 3)) SWIG_fail;
/* store the size of the first array in the list, then use that for comparison. */
if (i == 0)
{
size[0] = array_size(temp_array,0);
size[1] = array_size(temp_array,1);
size[2] = array_size(temp_array,2);
}
if (!require_size(temp_array, size, 3)) SWIG_fail;
array[i] = (DATA_TYPE*) array_data(temp_array);
}
$1 = (DATA_TYPE**) array;
$3 = (DIM_TYPE) size[0];
$4 = (DIM_TYPE) size[1];
$5 = (DIM_TYPE) size[2];
}
%typemap(freearg)
(DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
Py_ssize_t i;
if (array$argnum!=NULL) free(array$argnum);
/*freeing the individual arrays if needed */
if (object_array$argnum!=NULL)
{
if (is_new_object_array$argnum!=NULL)
{
for (i=0; i<$2; i++)
{
if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
{ Py_DECREF(object_array$argnum[i]); }
}
free(is_new_object_array$argnum);
}
free(object_array$argnum);
}
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
* DATA_TYPE* IN_ARRAY4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[4] = { -1, -1, -1 , -1};
array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 4) ||
!require_size(array, size, 4)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DIM_TYPE) array_size(array,2);
$4 = (DIM_TYPE) array_size(array,3);
$5 = (DATA_TYPE*) array_data(array);
}
%typemap(freearg)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3, DIM_TYPE DIM4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[4] = { -1, -1, -1, -1 };
array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 4) ||
!require_size(array, size, 4) | !require_fortran(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
$4 = (DIM_TYPE) array_size(array,2);
$5 = (DIM_TYPE) array_size(array,3);
}
%typemap(freearg)
(DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
* DATA_TYPE* IN_FARRAY4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
{
$1 = is_array($input) || PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[4] = { -1, -1, -1 , -1 };
array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
&is_new_object);
if (!array || !require_dimensions(array, 4) ||
!require_size(array, size, 4) || !require_fortran(array)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DIM_TYPE) array_size(array,2);
$4 = (DIM_TYPE) array_size(array,3);
$5 = (DATA_TYPE*) array_data(array);
}
%typemap(freearg)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
{
if (is_new_object$argnum && array$argnum)
{ Py_DECREF(array$argnum); }
}
/***************************/
/* In-Place Array Typemaps */
/***************************/
/* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY])
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE INPLACE_ARRAY1[ANY])
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE INPLACE_ARRAY1[ANY])
(PyArrayObject* array=NULL)
{
npy_intp size[1] = { $1_dim0 };
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) ||
!require_contiguous(array) || !require_native(array)) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
(PyArrayObject* array=NULL, int i=1)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,1) || !require_contiguous(array)
|| !require_native(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = 1;
for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i);
}
/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
(PyArrayObject* array=NULL, int i=0)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,1) || !require_contiguous(array)
|| !require_native(array)) SWIG_fail;
$1 = 1;
for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i);
$2 = (DATA_TYPE*) array_data(array);
}
/* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
(PyArrayObject* array=NULL)
{
npy_intp size[2] = { $1_dim0, $1_dim1 };
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) ||
!require_contiguous(array) || !require_native(array)) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,2) || !require_contiguous(array)
|| !require_native(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
!require_native(array)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DATA_TYPE*) array_data(array);
}
/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,2) || !require_contiguous(array)
|| !require_native(array) || !require_fortran(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
!require_native(array) || !require_fortran(array)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DATA_TYPE*) array_data(array);
}
/* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
(PyArrayObject* array=NULL)
{
npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) ||
!require_contiguous(array) || !require_native(array)) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
!require_native(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
$4 = (DIM_TYPE) array_size(array,2);
}
/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
$1 = PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
(DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
{
npy_intp size[2] = { -1, -1 };
PyArrayObject* temp_array;
Py_ssize_t i;
/* length of the list */
$2 = PyList_Size($input);
/* the arrays */
array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
if (array == NULL || object_array == NULL)
{
SWIG_fail;
}
for (i=0; i<$2; i++)
{
temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
/* the new array must be stored so that it can be destroyed in freearg */
object_array[i] = temp_array;
if ( !temp_array || !require_dimensions(temp_array, 2) ||
!require_contiguous(temp_array) ||
!require_native(temp_array) ||
!PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
) SWIG_fail;
/* store the size of the first array in the list, then use that for comparison. */
if (i == 0)
{
size[0] = array_size(temp_array,0);
size[1] = array_size(temp_array,1);
}
if (!require_size(temp_array, size, 2)) SWIG_fail;
array[i] = (DATA_TYPE*) array_data(temp_array);
}
$1 = (DATA_TYPE**) array;
$3 = (DIM_TYPE) size[0];
$4 = (DIM_TYPE) size[1];
}
%typemap(freearg)
(DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
if (array$argnum!=NULL) free(array$argnum);
if (object_array$argnum!=NULL) free(object_array$argnum);
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
* DATA_TYPE* INPLACE_ARRAY3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,3) || !require_contiguous(array)
|| !require_native(array)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DIM_TYPE) array_size(array,2);
$4 = (DATA_TYPE*) array_data(array);
}
/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
!require_native(array) || !require_fortran(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
$4 = (DIM_TYPE) array_size(array,2);
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
* DATA_TYPE* INPLACE_FARRAY3)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,3) || !require_contiguous(array)
|| !require_native(array) || !require_fortran(array)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DIM_TYPE) array_size(array,2);
$4 = (DATA_TYPE*) array_data(array);
}
/* Typemap suite for (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
(PyArrayObject* array=NULL)
{
npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3 };
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,4) || !require_size(array, size, 4) ||
!require_contiguous(array) || !require_native(array)) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3, DIM_TYPE DIM4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
!require_native(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
$4 = (DIM_TYPE) array_size(array,2);
$5 = (DIM_TYPE) array_size(array,3);
}
/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3, DIM_TYPE DIM4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
$1 = PySequence_Check($input);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
{
npy_intp size[3] = { -1, -1, -1 };
PyArrayObject* temp_array;
Py_ssize_t i;
/* length of the list */
$2 = PyList_Size($input);
/* the arrays */
array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
if (array == NULL || object_array == NULL)
{
SWIG_fail;
}
for (i=0; i<$2; i++)
{
temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
/* the new array must be stored so that it can be destroyed in freearg */
object_array[i] = temp_array;
if ( !temp_array || !require_dimensions(temp_array, 3) ||
!require_contiguous(temp_array) ||
!require_native(temp_array) ||
!PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
) SWIG_fail;
/* store the size of the first array in the list, then use that for comparison. */
if (i == 0)
{
size[0] = array_size(temp_array,0);
size[1] = array_size(temp_array,1);
size[2] = array_size(temp_array,2);
}
if (!require_size(temp_array, size, 3)) SWIG_fail;
array[i] = (DATA_TYPE*) array_data(temp_array);
}
$1 = (DATA_TYPE**) array;
$3 = (DIM_TYPE) size[0];
$4 = (DIM_TYPE) size[1];
$5 = (DIM_TYPE) size[2];
}
%typemap(freearg)
(DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
if (array$argnum!=NULL) free(array$argnum);
if (object_array$argnum!=NULL) free(object_array$argnum);
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
* DATA_TYPE* INPLACE_ARRAY4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,4) || !require_contiguous(array)
|| !require_native(array)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DIM_TYPE) array_size(array,2);
$4 = (DIM_TYPE) array_size(array,3);
$5 = (DATA_TYPE*) array_data(array);
}
/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
* DIM_TYPE DIM3, DIM_TYPE DIM4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
!require_native(array) || !require_fortran(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
$2 = (DIM_TYPE) array_size(array,0);
$3 = (DIM_TYPE) array_size(array,1);
$4 = (DIM_TYPE) array_size(array,2);
$5 = (DIM_TYPE) array_size(array,3);
}
/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
* DATA_TYPE* INPLACE_FARRAY4)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
(PyArrayObject* array=NULL)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,4) || !require_contiguous(array)
|| !require_native(array) || !require_fortran(array)) SWIG_fail;
$1 = (DIM_TYPE) array_size(array,0);
$2 = (DIM_TYPE) array_size(array,1);
$3 = (DIM_TYPE) array_size(array,2);
$4 = (DIM_TYPE) array_size(array,3);
$5 = (DATA_TYPE*) array_data(array);
}
/*************************/
/* Argout Array Typemaps */
/*************************/
/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY])
*/
%typemap(in,numinputs=0,
fragment="NumPy_Backward_Compatibility,NumPy_Macros")
(DATA_TYPE ARGOUT_ARRAY1[ANY])
(PyObject* array = NULL)
{
npy_intp dims[1] = { $1_dim0 };
array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
if (!array) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
%typemap(argout)
(DATA_TYPE ARGOUT_ARRAY1[ANY])
{
$result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
}
/* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
*/
%typemap(in,numinputs=1,
fragment="NumPy_Fragments")
(DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
(PyObject* array = NULL)
{
npy_intp dims[1];
if (!PyInt_Check($input))
{
const char* typestring = pytype_string($input);
PyErr_Format(PyExc_TypeError,
"Int dimension expected. '%s' given.",
typestring);
SWIG_fail;
}
$2 = (DIM_TYPE) PyInt_AsLong($input);
dims[0] = (npy_intp) $2;
array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
if (!array) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
}
%typemap(argout)
(DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
{
$result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
}
/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
*/
%typemap(in,numinputs=1,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
(PyObject* array = NULL)
{
npy_intp dims[1];
if (!PyInt_Check($input))
{
const char* typestring = pytype_string($input);
PyErr_Format(PyExc_TypeError,
"Int dimension expected. '%s' given.",
typestring);
SWIG_fail;
}
$1 = (DIM_TYPE) PyInt_AsLong($input);
dims[0] = (npy_intp) $1;
array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
if (!array) SWIG_fail;
$2 = (DATA_TYPE*) array_data(array);
}
%typemap(argout)
(DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
{
$result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
}
/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
*/
%typemap(in,numinputs=0,
fragment="NumPy_Backward_Compatibility,NumPy_Macros")
(DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
(PyObject* array = NULL)
{
npy_intp dims[2] = { $1_dim0, $1_dim1 };
array = PyArray_SimpleNew(2, dims, DATA_TYPECODE);
if (!array) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
%typemap(argout)
(DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
{
$result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
}
/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
*/
%typemap(in,numinputs=0,
fragment="NumPy_Backward_Compatibility,NumPy_Macros")
(DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
(PyObject* array = NULL)
{
npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 };
array = PyArray_SimpleNew(3, dims, DATA_TYPECODE);
if (!array) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
%typemap(argout)
(DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
{
$result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
}
/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
*/
%typemap(in,numinputs=0,
fragment="NumPy_Backward_Compatibility,NumPy_Macros")
(DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
(PyObject* array = NULL)
{
npy_intp dims[4] = { $1_dim0, $1_dim1, $1_dim2, $1_dim3 };
array = PyArray_SimpleNew(4, dims, DATA_TYPECODE);
if (!array) SWIG_fail;
$1 = ($1_ltype) array_data(array);
}
%typemap(argout)
(DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
{
$result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
}
/*****************************/
/* Argoutview Array Typemaps */
/*****************************/
/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp)
{
$1 = &data_temp;
$2 = &dim_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
{
npy_intp dims[1] = { *$2 };
PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEW_ARRAY1)
(DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim_temp;
$2 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
{
npy_intp dims[1] = { *$1 };
PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
{
npy_intp dims[2] = { *$2, *$3 };
PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_ARRAY2)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
{
npy_intp dims[2] = { *$1, *$2 };
PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
{
npy_intp dims[2] = { *$2, *$3 };
PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || !require_fortran(array)) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_FARRAY2)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
{
npy_intp dims[2] = { *$1, *$2 };
PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || !require_fortran(array)) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
{
npy_intp dims[3] = { *$2, *$3, *$4 };
PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
DATA_TYPE** ARGOUTVIEW_ARRAY3)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL)
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
{
npy_intp dims[3] = { *$1, *$2, *$3 };
PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
{
npy_intp dims[3] = { *$2, *$3, *$4 };
PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
DATA_TYPE** ARGOUTVIEW_FARRAY3)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEW_FARRAY3)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
{
npy_intp dims[3] = { *$1, *$2, *$3 };
PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3, DIM_TYPE* DIM4)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
$5 = &dim4_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
{
npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
DATA_TYPE** ARGOUTVIEW_ARRAY4)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_ARRAY4)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &dim4_temp;
$5 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
{
npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3, DIM_TYPE* DIM4)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
$5 = &dim4_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
{
npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
DATA_TYPE** ARGOUTVIEW_FARRAY4)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_FARRAY4)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &dim4_temp;
$5 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
{
npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,obj);
}
/*************************************/
/* Managed Argoutview Array Typemaps */
/*************************************/
/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp)
{
$1 = &data_temp;
$2 = &dim_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
{
npy_intp dims[1] = { *$2 };
PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEWM_ARRAY1)
(DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim_temp;
$2 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
{
npy_intp dims[1] = { *$1 };
PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
{
npy_intp dims[2] = { *$2, *$3 };
PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_ARRAY2)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
{
npy_intp dims[2] = { *$1, *$2 };
PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
{
npy_intp dims[2] = { *$2, *$3 };
PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || !require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_FARRAY2)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
{
npy_intp dims[2] = { *$1, *$2 };
PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || !require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
{
npy_intp dims[3] = { *$2, *$3, *$4 };
PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
DATA_TYPE** ARGOUTVIEWM_ARRAY3)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_ARRAY3)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
{
npy_intp dims[3] = { *$1, *$2, *$3 };
PyObject* obj= PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
{
npy_intp dims[3] = { *$2, *$3, *$4 };
PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
DATA_TYPE** ARGOUTVIEWM_FARRAY3)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_FARRAY3)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
{
npy_intp dims[3] = { *$1, *$2, *$3 };
PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3, DIM_TYPE* DIM4)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
$5 = &dim4_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
{
npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
DATA_TYPE** ARGOUTVIEWM_ARRAY4)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &dim4_temp;
$5 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
{
npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3, DIM_TYPE* DIM4)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
$5 = &dim4_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
{
npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
DATA_TYPE** ARGOUTVIEWM_FARRAY4)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &dim4_temp;
$5 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
{
npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3, DIM_TYPE* DIM4)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
$5 = &dim4_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
{
npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
DATA_TYPE** ARGOUTVIEWM_ARRAY4)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &dim4_temp;
$5 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
{
npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
DIM_TYPE* DIM3, DIM_TYPE* DIM4)
*/
%typemap(in,numinputs=0)
(DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
(DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
{
$1 = &data_temp;
$2 = &dim1_temp;
$3 = &dim2_temp;
$4 = &dim3_temp;
$5 = &dim4_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
{
npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
DATA_TYPE** ARGOUTVIEWM_FARRAY4)
*/
%typemap(in,numinputs=0)
(DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
(DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
{
$1 = &dim1_temp;
$2 = &dim2_temp;
$3 = &dim3_temp;
$4 = &dim4_temp;
$5 = &data_temp;
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
{
npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
PyArrayObject* array = (PyArrayObject*) obj;
if (!array || require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
%#else
PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
PyArray_BASE(array) = cap;
%#else
PyArray_SetBaseObject(array,cap);
%#endif
$result = SWIG_Python_AppendOutput($result,obj);
}
%enddef /* %numpy_typemaps() macro */
/* *************************************************************** */
/* Concrete instances of the %numpy_typemaps() macro: Each invocation
* below applies all of the typemaps above to the specified data type.
*/
%numpy_typemaps(signed char , NPY_BYTE , int)
%numpy_typemaps(unsigned char , NPY_UBYTE , int)
%numpy_typemaps(short , NPY_SHORT , int)
%numpy_typemaps(unsigned short , NPY_USHORT , int)
%numpy_typemaps(int , NPY_INT , int)
%numpy_typemaps(unsigned int , NPY_UINT , int)
%numpy_typemaps(long , NPY_LONG , int)
%numpy_typemaps(unsigned long , NPY_ULONG , int)
%numpy_typemaps(long long , NPY_LONGLONG , int)
%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
%numpy_typemaps(float , NPY_FLOAT , int)
%numpy_typemaps(double , NPY_DOUBLE , int)
/* ***************************************************************
* The follow macro expansion does not work, because C++ bool is 4
* bytes and NPY_BOOL is 1 byte
*
* %numpy_typemaps(bool, NPY_BOOL, int)
*/
/* ***************************************************************
* On my Mac, I get the following warning for this macro expansion:
* 'swig/python detected a memory leak of type 'long double *', no destructor found.'
*
* %numpy_typemaps(long double, NPY_LONGDOUBLE, int)
*/
/* ***************************************************************
* Swig complains about a syntax error for the following macro
* expansions:
*
* %numpy_typemaps(complex float, NPY_CFLOAT , int)
*
* %numpy_typemaps(complex double, NPY_CDOUBLE, int)
*
* %numpy_typemaps(complex long double, NPY_CLONGDOUBLE, int)
*/
#endif /* SWIGPYTHON */
diff --git a/python/swig/solid_mechanics_model.i b/python/swig/solid_mechanics_model.i
index c9ed3632b..02bc691af 100644
--- a/python/swig/solid_mechanics_model.i
+++ b/python/swig/solid_mechanics_model.i
@@ -1,179 +1,211 @@
+/**
+ * @file solid_mechanics_model.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Dec 12 2014
+ * @date last modification: Wed Jan 06 2016
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%{
#include "solid_mechanics_model.hh"
#include "sparse_matrix.hh"
#include "boundary_condition.hh"
#include "boundary_condition_functor.hh"
#include "boundary_condition_python_functor.hh"
#include "material_python.hh"
%}
namespace akantu {
%ignore SolidMechanicsModel::initFEEngineBoundary;
%ignore SolidMechanicsModel::initParallel;
%ignore SolidMechanicsModel::initArrays;
%ignore SolidMechanicsModel::initModel;
%ignore SolidMechanicsModel::initPBC;
%ignore SolidMechanicsModel::initExplicit;
%ignore SolidMechanicsModel::isExplicit;
%ignore SolidMechanicsModel::updateCurrentPosition;
%ignore SolidMechanicsModel::updateAcceleration;
%ignore SolidMechanicsModel::updateIncrement;
%ignore SolidMechanicsModel::updatePreviousDisplacement;
%ignore SolidMechanicsModel::saveStressAndStrainBeforeDamage;
%ignore SolidMechanicsModel::updateEnergiesAfterDamage;
%ignore SolidMechanicsModel::solveLumped;
%ignore SolidMechanicsModel::explicitPred;
%ignore SolidMechanicsModel::explicitCorr;
%ignore SolidMechanicsModel::initSolver;
%ignore SolidMechanicsModel::initImplicit;
%ignore SolidMechanicsModel::initialAcceleration;
%ignore SolidMechanicsModel::testConvergence;
%ignore SolidMechanicsModel::testConvergenceIncrement;
%ignore SolidMechanicsModel::testConvergenceResidual;
%ignore SolidMechanicsModel::initVelocityDampingMatrix;
%ignore SolidMechanicsModel::getNbDataForElements;
%ignore SolidMechanicsModel::packElementData;
%ignore SolidMechanicsModel::unpackElementData;
%ignore SolidMechanicsModel::getNbDataToPack;
%ignore SolidMechanicsModel::getNbDataToUnpack;
%ignore SolidMechanicsModel::packData;
%ignore SolidMechanicsModel::unpackData;
%ignore SolidMechanicsModel::setMaterialSelector;
%ignore SolidMechanicsModel::getSolver;
%ignore SolidMechanicsModel::getSynchronizer;
%ignore Dumpable::registerExternalDumper;
}
%template(SolidMechanicsBoundaryCondition) akantu::BoundaryCondition<akantu::SolidMechanicsModel>;
%include "dumpable.hh"
print_self(SolidMechanicsModel)
%include "solid_mechanics_model.hh"
%extend akantu::SolidMechanicsModel {
/* ------------------------------------------------------------------------ */
bool testConvergenceSccRes(Real tolerance) {
Real error = 0;
bool res = self->testConvergence<akantu::_scc_residual>(tolerance, error);
return res;
}
/* ------------------------------------------------------------------------ */
void solveStaticDisplacement(Real tolerance, UInt max_iteration) {
$self->solveStatic<akantu::_scm_newton_raphson_tangent_not_computed,
akantu::_scc_residual>(tolerance, max_iteration);
}
/* ------------------------------------------------------------------------ */
/// register an empty material of a given type
void registerNewPythonMaterial(PyObject * obj, const akantu::ID & mat_type) {
std::pair<akantu::Parser::const_section_iterator,
akantu::Parser::const_section_iterator>
sub_sect = akantu::getStaticParser().getSubSections(akantu::_st_material);
akantu::Parser::const_section_iterator it = sub_sect.first;
for (; it != sub_sect.second; ++it) {
if (it->getName() == mat_type) {
AKANTU_DEBUG_ASSERT($self->materials_names_to_id.find(mat_type) ==
$self->materials_names_to_id.end(),
"A material with this name '"
<< mat_type << "' has already been registered. "
<< "Please use unique names for materials");
UInt mat_count = $self->materials.size();
$self->materials_names_to_id[mat_type] = mat_count;
std::stringstream sstr_mat;
sstr_mat << $self->getID() << ":" << mat_count << ":" << mat_type;
akantu::ID mat_id = sstr_mat.str();
akantu::Material * material = new akantu::MaterialPython(*$self, obj, mat_id);
$self->materials.push_back(material);
material->parseSection(*it);
}
}
}
/* ------------------------------------------------------------------------ */
void applyDirichletBC(PyObject * func_obj, const std::string & group_name) {
akantu::BC::PythonFunctorDirichlet functor(func_obj);
$self->applyBC(functor, group_name);
}
/* ------------------------------------------------------------------------ */
void applyNeumannBC(PyObject * func_obj, const std::string & group_name) {
akantu::BC::PythonFunctorNeumann functor(func_obj);
$self->applyBC(functor, group_name);
}
/* ------------------------------------------------------------------------ */
void solveDisplCorr(bool need_factorize, bool has_profile_changed) {
akantu::Array<akantu::Real> & increment = $self->getIncrement();
$self->solve<akantu::IntegrationScheme2ndOrder::_displacement_corrector>(
increment, 1., need_factorize, has_profile_changed);
}
/* ------------------------------------------------------------------------ */
void clearDispl() {
akantu::Array<akantu::Real> & displ = $self->getDisplacement();
displ.clear();
}
/* ------------------------------------------------------------------------ */
void solveStep_TgModifIncr(Real tolerance, UInt max_iteration) {
$self->solveStep<akantu::_scm_newton_raphson_tangent_modified,
akantu::_scc_increment>(tolerance, max_iteration);
}
/* ------------------------------------------------------------------------ */
void solveStep_TgIncr(Real tolerance, Real & error, UInt max_iteration) {
$self->solveStep<akantu::_scm_newton_raphson_tangent,
akantu::_scc_increment>(tolerance, error, max_iteration);
}
/* ------------------------------------------------------------------------ */
void clearDisplVeloAcc() {
akantu::Array<akantu::Real> & displ = $self->getDisplacement();
akantu::Array<akantu::Real> & velo = $self->getVelocity();
akantu::Array<akantu::Real> & acc = $self->getAcceleration();
displ.clear();
velo.clear();
acc.clear();
}
/* ------------------------------------------------------------------------ */
void applyUniformPressure(Real pressure, const std::string surface_name) {
UInt spatial_dimension = $self->getSpatialDimension();
akantu::Matrix<akantu::Real> surface_stress(spatial_dimension,
spatial_dimension, 0.0);
for (UInt i = 0; i < spatial_dimension; ++i) {
surface_stress(i, i) = -pressure;
}
$self->applyBC(akantu::BC::Neumann::FromStress(surface_stress),
surface_name);
}
/* ------------------------------------------------------------------------ */
void blockDOF(const std::string surface_name, SpacialDirection direction) {
$self->applyBC(akantu::BC::Dirichlet::FixedValue(0.0, direction),
surface_name);
}
}
diff --git a/python/swig/solid_mechanics_model_cohesive.i b/python/swig/solid_mechanics_model_cohesive.i
index c92801f82..236a756c3 100644
--- a/python/swig/solid_mechanics_model_cohesive.i
+++ b/python/swig/solid_mechanics_model_cohesive.i
@@ -1,24 +1,56 @@
+/**
+ * @file solid_mechanics_model_cohesive.i
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Mon Nov 23 2015
+ * @date last modification: Wed Jan 13 2016
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%{
#include "cohesive_element_inserter.hh"
#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive.hh"
%}
namespace akantu {
%ignore SolidMechanicsModelCohesive::initFacetFilter;
%ignore SolidMechanicsModelCohesive::initParallel;
%ignore CohesiveElementInserter::initParallel;
}
%extend akantu::SolidMechanicsModelCohesive {
Array<Real> & getRealInternalCohesiveField(const std::string field_name) {
akantu::Mesh & mesh = $self->getMesh();
akantu::ElementType type = *(mesh.firstType(mesh.getSpatialDimension(), akantu::_not_ghost, akantu::_ek_cohesive));
return ($self->flattenInternal(field_name,akantu::_ek_cohesive, akantu::_not_ghost))(type);
}
}
%include "cohesive_element_inserter.hh"
%include "solid_mechanics_model_cohesive.hh"
diff --git a/python/swig/structural_mechanics_model.i b/python/swig/structural_mechanics_model.i
index c6f45e515..97205ffa7 100644
--- a/python/swig/structural_mechanics_model.i
+++ b/python/swig/structural_mechanics_model.i
@@ -1,40 +1,69 @@
+/**
+ * @file structural_mechanics_model.i
+ *
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ *
+ * @date creation: Wed Apr 01 2015
+ *
+ * @brief
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
%{
#include "structural_mechanics_model.hh"
#include "sparse_matrix.hh"
%}
namespace akantu {
%ignore StructuralMechanicsModel::initArrays;
%ignore StructuralMechanicsModel::initModel;
%ignore StructuralMechanicsModel::initSolver;
%ignore StructuralMechanicsModel::initImplicit;
static void lin_load(double * position, double * load,
__attribute__ ((unused)) Real * normal,
__attribute__ ((unused)) UInt surface_id) {
memset(load,0,sizeof(Real)*3);
if (position[0]<=10){
load[1]= -6000;
}
}
}
%include "dumpable.hh"
%include "structural_mechanics_model.hh"
%extend akantu::StructuralMechanicsModel {
bool solveStep(Real tolerance, UInt max_iteration) {
return $self->solveStep<akantu::SolveConvergenceMethod::_scm_newton_raphson_tangent, akantu::SolveConvergenceCriteria::_scc_residual>(tolerance, max_iteration);
}
void computeForcesFromFunctionBeam2d(BoundaryFunctionType function_type) {
$self->computeForcesFromFunction<akantu::ElementType::_bernoulli_beam_2>(akantu::lin_load, function_type);
}
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7570d8d50..aa03e3851 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,160 +1,161 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Nov 28 2011
-# @date last modification: Tue Sep 16 2014
+# @date last modification: Wed Jan 13 2016
#
# @brief CMake file for the library
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
#===============================================================================
# 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
)
#===========================================================================
# 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
MACRO_NAMESPACE "AKA_FC_")
mark_as_advanced(CDEFS)
list(APPEND AKANTU_LIBRARY_PUBLIC_HDRS
${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})
#===========================================================================
# 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})
generate_material_list()
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()
#===============================================================================
# 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 LINK_INTERFACE_MULTIPLICITY 0)
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()
set_target_properties(akantu PROPERTIES ${AKANTU_LIBRARY_PROPERTIES})
set_target_properties(akantu PROPERTIES PUBLIC_HEADER "${AKANTU_LIBRARY_PUBLIC_HDRS}")
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)
diff --git a/src/common/aka_array.cc b/src/common/aka_array.cc
index 45a8a3211..2c4afbef4 100644
--- a/src/common/aka_array.cc
+++ b/src/common/aka_array.cc
@@ -1,115 +1,116 @@
/**
* @file aka_array.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Fri Mar 21 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief Implementation of akantu::Array
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <memory>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Functions ArrayBase */
/* -------------------------------------------------------------------------- */
ArrayBase::ArrayBase(const ID & id) :
id(id), allocated_size(0), size(0), nb_component(1), size_of_type(0) {
}
/* -------------------------------------------------------------------------- */
ArrayBase::~ArrayBase() {
}
/* -------------------------------------------------------------------------- */
void ArrayBase::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "ArrayBase [" << std::endl;
stream << space << " + size : " << size << std::endl;
stream << space << " + nb component : " << nb_component << std::endl;
stream << space << " + allocated size : " << allocated_size << std::endl;
Real mem_size = (allocated_size * nb_component * size_of_type) / 1024.;
stream << space << " + size of type : " << size_of_type << "B" << std::endl;
stream << space << " + memory allocated : " << mem_size << "kB" << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
template <> Int Array<Real>::find(const Real & elem) const {
AKANTU_DEBUG_IN();
UInt i = 0;
Real epsilon = std::numeric_limits<Real>::epsilon();
for (; (i < size) && (fabs(values[i] - elem) <= epsilon); ++i);
AKANTU_DEBUG_OUT();
return (i == size) ? -1 : (Int) i;
}
/* -------------------------------------------------------------------------- */
template <>
Array<ElementType> & Array<ElementType>::operator*=(__attribute__((unused)) const ElementType & alpha) {
AKANTU_DEBUG_TO_IMPLEMENT();
return *this;
}
template <>
Array<ElementType> & Array<ElementType>::operator-=(__attribute__((unused)) const Array<ElementType> & vect) {
AKANTU_DEBUG_TO_IMPLEMENT();
return *this;
}
template <>
Array<ElementType> & Array<ElementType>::operator+=(__attribute__((unused)) const Array<ElementType> & vect) {
AKANTU_DEBUG_TO_IMPLEMENT();
return *this;
}
template <>
Array<char> & Array<char>::operator*=(__attribute__((unused)) const char & alpha) {
AKANTU_DEBUG_TO_IMPLEMENT();
return *this;
}
template <>
Array<char> & Array<char>::operator-=(__attribute__((unused)) const Array<char> & vect) {
AKANTU_DEBUG_TO_IMPLEMENT();
return *this;
}
template <>
Array<char> & Array<char>::operator+=(__attribute__((unused)) const Array<char> & vect) {
AKANTU_DEBUG_TO_IMPLEMENT();
return *this;
}
__END_AKANTU__
diff --git a/src/common/aka_array.hh b/src/common/aka_array.hh
index d369d83e3..97c2fa449 100644
--- a/src/common/aka_array.hh
+++ b/src/common/aka_array.hh
@@ -1,368 +1,369 @@
/**
* @file aka_array.hh
*
* @author Till Junge <till.junge@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Tue Jun 24 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief Array container for Akantu
* This container differs from the std::vector from the fact it as 2 dimensions
* a main dimension and the size stored per entries
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_VECTOR_HH__
#define __AKANTU_VECTOR_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#include <typeinfo>
#include <vector>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/// class that afford to store vectors in static memory
class ArrayBase {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ArrayBase(const ID & id = "");
virtual ~ArrayBase();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get the amount of space allocated in bytes
inline UInt getMemorySize() const;
/// set the size to zero without freeing the allocated space
inline void empty();
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Get the real size allocated in memory
AKANTU_GET_MACRO(AllocatedSize, allocated_size, UInt);
/// Get the Size of the Array
AKANTU_GET_MACRO(Size, size, UInt);
/// Get the number of components
AKANTU_GET_MACRO(NbComponent, nb_component, UInt);
/// Get the name of th array
AKANTU_GET_MACRO(ID, id, const ID &);
/// Set the name of th array
AKANTU_SET_MACRO(ID, id, const ID &);
// AKANTU_GET_MACRO(Tag, tag, const std::string &);
// AKANTU_SET_MACRO(Tag, tag, const std::string &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// id of the vector
ID id;
/// the size allocated
UInt allocated_size;
/// the size used
UInt size;
/// number of components
UInt nb_component;
/// size of the stored type
UInt size_of_type;
// /// User defined tag
// std::string tag;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<typename T, bool is_scal>
class Array : public ArrayBase {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef T value_type;
typedef value_type & reference;
typedef value_type * pointer_type;
typedef const value_type & const_reference;
/// Allocation of a new vector
inline Array(UInt size = 0, UInt nb_component = 1,
const ID & id = "");
/// Allocation of a new vector with a default value
Array(UInt size, UInt nb_component,
const value_type def_values[], const ID & id = "");
/// Allocation of a new vector with a default value
Array(UInt size, UInt nb_component,
const_reference value, const ID & id = "");
/// Copy constructor (deep copy if deep=true)
Array(const Array<value_type, is_scal>& vect, bool deep = true, const ID & id = "");
#ifndef SWIG
/// Copy constructor (deep copy)
Array(const std::vector<value_type> & vect);
#endif
virtual inline ~Array();
Array & operator=(const Array & a) {
/// this is to let STL allocate and copy arrays in the case of std::vector::resize
AKANTU_DEBUG_ASSERT(this->size == 0,"Cannot copy akantu::Array");
return const_cast<Array&>(a);
}
/* ------------------------------------------------------------------------ */
/* Iterator */
/* ------------------------------------------------------------------------ */
/// \todo protected: does not compile with intel check why
public:
template <class R, class IR = R, bool issame = is_same<IR, T>::value >
class iterator_internal;
public:
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
template<typename R = T> class const_iterator;
template<typename R = T> class iterator;
/* ------------------------------------------------------------------------ */
/// iterator for Array of nb_component = 1
typedef iterator< T > scalar_iterator;
/// const_iterator for Array of nb_component = 1
typedef const_iterator< T > const_scalar_iterator;
/// iterator rerturning Vectors of size n on entries of Array with nb_component = n
typedef iterator< Vector<T> > vector_iterator;
/// const_iterator rerturning Vectors of n size on entries of Array with nb_component = n
typedef const_iterator< Vector<T> > const_vector_iterator;
/// iterator rerturning Matrices of size (m, n) on entries of Array with nb_component = m*n
typedef iterator< Matrix<T> > matrix_iterator;
/// const iterator rerturning Matrices of size (m, n) on entries of Array with nb_component = m*n
typedef const_iterator< Matrix<T> > const_matrix_iterator;
/* ------------------------------------------------------------------------ */
/// Get an iterator that behaves like a pointer T * to the first entry
inline scalar_iterator begin();
/// Get an iterator that behaves like a pointer T * to the end of the Array
inline scalar_iterator end();
/// Get a const_iterator to the beginging of an Array of scalar
inline const_scalar_iterator begin() const;
/// Get a const_iterator to the end of an Array of scalar
inline const_scalar_iterator end() const;
/* ------------------------------------------------------------------------ */
/// Get a vector_iterator on the begining of the Array
inline vector_iterator begin(UInt n);
/// Get a vector_iterator on the end of the Array
inline vector_iterator end(UInt n);
/// Get a vector_iterator on the begining of the Array
inline const_vector_iterator begin(UInt n) const;
/// Get a vector_iterator on the end of the Array
inline const_vector_iterator end(UInt n) const;
/// Get a vector_iterator on the begining of the Array considered of shape (new_size, n)
inline vector_iterator begin_reinterpret(UInt n, UInt new_size);
/// Get a vector_iterator on the end of the Array considered of shape (new_size, n)
inline vector_iterator end_reinterpret(UInt n, UInt new_size);
/// Get a const_vector_iterator on the begining of the Array considered of shape (new_size, n)
inline const_vector_iterator begin_reinterpret(UInt n, UInt new_size) const;
/// Get a const_vector_iterator on the end of the Array considered of shape (new_size, n)
inline const_vector_iterator end_reinterpret(UInt n, UInt new_size) const;
/* ------------------------------------------------------------------------ */
/// Get a matrix_iterator on the begining of the Array (Matrices of size (m, n))
inline matrix_iterator begin(UInt m, UInt n);
/// Get a matrix_iterator on the end of the Array (Matrices of size (m, n))
inline matrix_iterator end(UInt m, UInt n);
/// Get a const_matrix_iterator on the begining of the Array (Matrices of size (m, n))
inline const_matrix_iterator begin(UInt m, UInt n) const;
/// Get a const_matrix_iterator on the end of the Array (Matrices of size (m, n))
inline const_matrix_iterator end(UInt m, UInt n) const;
/// Get a matrix_iterator on the begining of the Array considered of shape (new_size, m*n)
inline matrix_iterator begin_reinterpret(UInt m, UInt n, UInt size);
/// Get a matrix_iterator on the end of the Array considered of shape (new_size, m*n)
inline matrix_iterator end_reinterpret(UInt m, UInt n, UInt size);
/// Get a const_matrix_iterator on the begining of the Array considered of shape (new_size, m*n)
inline const_matrix_iterator begin_reinterpret(UInt m, UInt n, UInt size) const;
/// Get a const_matrix_iterator on the end of the Array considered of shape (new_size, m*n)
inline const_matrix_iterator end_reinterpret(UInt m, UInt n, UInt size) const;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// append a tuple of size nb_component containing value
inline void push_back(const_reference value);
/// append a vector
inline void push_back(const value_type new_elem[]);
/// append a Vector or a Matrix
template<template<typename> class C>
inline void push_back(const C<T> & new_elem);
/// append the value of the iterator
template<typename Ret>
inline void push_back(const iterator<Ret> & it);
/// erase the value at position i
inline void erase(UInt i);
/// ask Nico, clarify
template<typename R>
inline iterator<R> erase(const iterator<R> & it);
/// change the size of the Array
virtual void resize(UInt size);
/// change the number of components by interlacing data
/// @param multiplicator number of interlaced components add
/// @param block_size blocks of data in the array
/// Examaple for block_size = 2, multiplicator = 2
/// array = oo oo oo -> new array = oo nn nn oo nn nn oo nn nn
void extendComponentsInterlaced(UInt multiplicator, UInt stride);
/// search elem in the vector, return the position of the first occurrence or -1 if not found
Int find(const_reference elem) const;\
/// @see Array::find(const_reference elem) const
Int find(T elem[]) const;
/// set all entries of the array to 0
inline void clear() { std::fill_n(values, size*nb_component, T()); }
/// set all entries of the array to the value t
/// @param t value to fill the array with
inline void set(T t) { std::fill_n(values, size*nb_component, t); }
/// set all tuples of the array to a given vector or matrix
/// @param vm Matrix or Vector to fill the array with
template<template<typename> class C>
inline void set(const C<T> & vm);
/// copy another Array in the current Array, the no_sanity_check allows you to
/// force the copy in cases where you know what you do with two non matching
/// Arrays in terms of n
void copy(const Array<T, is_scal> & other, bool no_sanity_check = false);
/// give the address of the memory allocated for this vector
T * storage() const { return values; };
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
/// perform the allocation for the constructors
void allocate(UInt size, UInt nb_component = 1);
/// resize without initializing the memory
void resizeUnitialized(UInt new_size);
/* ------------------------------------------------------------------------ */
/* Operators */
/* ------------------------------------------------------------------------ */
public:
/// substraction entry-wise
Array<T, is_scal> & operator-=(const Array<T, is_scal> & other);
/// addition entry-wise
Array<T, is_scal> & operator+=(const Array<T, is_scal> & other);
/// multiply evry entry by alpha
Array<T, is_scal> & operator*=(const T & alpha);
/// check if the array are identical entry-wise
bool operator==(const Array<T, is_scal> & other) const;
/// @see Array::operator==(const Array<T, is_scal> & other) const
bool operator!=(const Array<T, is_scal> & other) const;
/// return a reference to the j-th entry of the i-th tuple
inline reference operator()(UInt i, UInt j = 0);
/// return a const reference to the j-th entry of the i-th tuple
inline const_reference operator()(UInt i, UInt j = 0) const;
/// return a reference to the ith component of the 1D array
inline reference operator[](UInt i);
/// return a const reference to the ith component of the 1D array
inline const_reference operator[](UInt i) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// array of values
T * values; // /!\ very dangerous
};
#include "aka_array_tmpl.hh"
__END_AKANTU__
#include "aka_types.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Inline Functions Array<T, is_scal> */
/* -------------------------------------------------------------------------- */
template <typename T, bool is_scal>
inline std::ostream & operator<<(std::ostream & stream, const Array<T, is_scal> & _this)
{
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
/* Inline Functions ArrayBase */
/* -------------------------------------------------------------------------- */
inline std::ostream & operator<<(std::ostream & stream, const ArrayBase & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_VECTOR_HH__ */
diff --git a/src/common/aka_array_tmpl.hh b/src/common/aka_array_tmpl.hh
index 5b5091e88..9f2188260 100644
--- a/src/common/aka_array_tmpl.hh
+++ b/src/common/aka_array_tmpl.hh
@@ -1,1298 +1,1299 @@
/**
* @file aka_array_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Fri Nov 06 2015
*
* @brief Inline functions of the classes Array<T> and ArrayBase
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* Inline Functions Array<T> */
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include <memory>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline T & Array<T, is_scal>::operator()(UInt i, UInt j) {
AKANTU_DEBUG_ASSERT(size > 0,
"The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size) && (j < nb_component),
"The value at position [" << i << "," << j
<< "] is out of range in array \"" << id << "\"");
return values[i*nb_component + j];
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline const T & Array<T, is_scal>::operator()(UInt i, UInt j) const {
AKANTU_DEBUG_ASSERT(size > 0,
"The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size) && (j < nb_component),
"The value at position [" << i << "," << j
<< "] is out of range in array \"" << id << "\"");
return values[i*nb_component + j];
}
template <class T, bool is_scal>
inline T & Array<T, is_scal>::operator[](UInt i) {
AKANTU_DEBUG_ASSERT(size > 0,
"The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size*nb_component),
"The value at position [" << i << "] is out of range in array \"" << id << "\"");
return values[i];
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline const T & Array<T, is_scal>::operator[](UInt i) const {
AKANTU_DEBUG_ASSERT(size > 0,
"The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size*nb_component),
"The value at position [" << i << "] is out of range in array \"" << id << "\"");
return values[i];
}
/* -------------------------------------------------------------------------- */
/**
* append a tuple to the array with the value value for all components
* @param value the new last tuple or the array will contain nb_component copies of value
*/
template <class T, bool is_scal>
inline void Array<T, is_scal>::push_back(const T & value) {
UInt pos = size;
resizeUnitialized(size+1);
std::uninitialized_fill_n(values + pos * nb_component, nb_component, value);
}
/* -------------------------------------------------------------------------- */
/**
* append a tuple to the array
* @param new_elem a C-array containing the values to be copied to the end of the array */
template <class T, bool is_scal>
inline void Array<T, is_scal>::push_back(const T new_elem[]) {
UInt pos = size;
resizeUnitialized(size+1);
T * tmp = values + nb_component * pos;
std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
}
/* -------------------------------------------------------------------------- */
/**
* append a matrix or a vector to the array
* @param new_elem a reference to a Matrix<T> or Vector<T> */
template <class T, bool is_scal>
template<template<typename> class C>
inline void Array<T, is_scal>::push_back(const C<T> & new_elem) {
AKANTU_DEBUG_ASSERT(nb_component == new_elem.size(),
"The vector("<< new_elem.size() <<") as not a size compatible with the Array (nb_component=" << nb_component << ").");
UInt pos = size;
resizeUnitialized(size+1);
T * tmp = values + nb_component * pos;
std::uninitialized_copy(new_elem.storage(), new_elem.storage() + nb_component, tmp);
}
/* -------------------------------------------------------------------------- */
/**
* append a tuple to the array
* @param it an iterator to the tuple to be copied to the end of the array */
template <class T, bool is_scal>
template<class Ret>
inline void Array<T, is_scal>::push_back(const Array<T, is_scal>::iterator<Ret> & it) {
UInt pos = size;
resizeUnitialized(size+1);
T * tmp = values + nb_component * pos;
T * new_elem = it.data();
std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
}
/* -------------------------------------------------------------------------- */
/**
* erase an element. If the erased element is not the last of the array, the
* last element is moved into the hole in order to maintain contiguity. This
* may invalidate existing iterators (For instance an iterator obtained by
* Array::end() is no longer correct) and will change the order of the
* elements.
* @param i index of element to erase
*/
template <class T, bool is_scal>
inline void Array<T, is_scal>::erase(UInt i){
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT((size > 0),
"The array is empty");
AKANTU_DEBUG_ASSERT((i < size),
"The element at position [" << i << "] is out of range (" << i << ">=" << size << ")");
if(i != (size - 1)) {
for (UInt j = 0; j < nb_component; ++j) {
values[i*nb_component + j] = values[(size-1)*nb_component + j];
}
}
resize(size - 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Subtract another array entry by entry from this array in place. Both arrays must
* have the same size and nb_component. If the arrays have different shapes,
* code compiled in debug mode will throw an expeption and optimised code
* will behave in an unpredicted manner
* @param other array to subtract from this
* @return reference to modified this
*/
template <class T, bool is_scal>
Array<T, is_scal> & Array<T, is_scal>::operator-=(const Array<T, is_scal> & vect) {
AKANTU_DEBUG_ASSERT((size == vect.size) && (nb_component == vect.nb_component),
"The too array don't have the same sizes");
T * a = values;
T * b = vect.storage();
for (UInt i = 0; i < size*nb_component; ++i) {
*a -= *b;
++a;++b;
}
return *this;
}
/* -------------------------------------------------------------------------- */
/**
* Add another array entry by entry to this array in place. Both arrays must
* have the same size and nb_component. If the arrays have different shapes,
* code compiled in debug mode will throw an expeption and optimised code
* will behave in an unpredicted manner
* @param other array to add to this
* @return reference to modified this
*/
template <class T, bool is_scal>
Array<T, is_scal> & Array<T, is_scal>::operator+=(const Array<T, is_scal> & vect) {
AKANTU_DEBUG_ASSERT((size == vect.size) && (nb_component == vect.nb_component),
"The too array don't have the same sizes");
T * a = values;
T * b = vect.storage();
for (UInt i = 0; i < size*nb_component; ++i) {
*a++ += *b++;
}
return *this;
}
/* -------------------------------------------------------------------------- */
/**
* Multiply all entries of this array by a scalar in place
* @param alpha scalar multiplicant
* @return reference to modified this
*/
template <class T, bool is_scal>
Array<T, is_scal> & Array<T, is_scal>::operator*=(const T & alpha) {
T * a = values;
for (UInt i = 0; i < size*nb_component; ++i) {
*a++ *= alpha;
}
return *this;
}
/* -------------------------------------------------------------------------- */
/**
* Compare this array element by element to another.
* @param other array to compare to
* @return true it all element are equal and arrays have the same shape, else false
*/
template <class T, bool is_scal>
bool Array<T, is_scal>::operator==(const Array<T, is_scal> & array) const {
bool equal = nb_component == array.nb_component && size == array.size && id == array.id;
if(!equal) return false;
if(values == array.storage()) return true;
else return std::equal(values, values + size*nb_component,
array.storage());
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
bool Array<T, is_scal>::operator!=(const Array<T, is_scal> & array) const {
return !operator==(array);
}
/* -------------------------------------------------------------------------- */
/**
* set all tuples of the array to a given vector or matrix
* @param vm Matrix or Vector to fill the array with
*/
template <class T, bool is_scal>
template<template<typename> class C>
inline void Array<T, is_scal>::set(const C<T> & vm) {
AKANTU_DEBUG_ASSERT(nb_component == vm.size(),
"The size of the object does not match the number of components");
for (T * it = values;
it < values + nb_component * size;
it += nb_component) {
std::copy(vm.storage(), vm.storage() + nb_component, it);
}
}
/* -------------------------------------------------------------------------- */
/* Functions Array<T, is_scal> */
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array (UInt size,
UInt nb_component,
const ID & id) :
ArrayBase(id), values(NULL) {
AKANTU_DEBUG_IN();
allocate(size, nb_component);
if(!is_scal) {
T val = T();
std::uninitialized_fill(values, values + size*nb_component, val);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array (UInt size,
UInt nb_component,
const T def_values[],
const ID & id) :
ArrayBase(id), values(NULL) {
AKANTU_DEBUG_IN();
allocate(size, nb_component);
T * tmp = values;
for (UInt i = 0; i < size; ++i) {
tmp = values + nb_component * i;
std::uninitialized_copy(def_values, def_values + nb_component, tmp);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array (UInt size,
UInt nb_component,
const T & value,
const ID & id) :
ArrayBase(id), values(NULL) {
AKANTU_DEBUG_IN();
allocate(size, nb_component);
std::uninitialized_fill_n(values, size*nb_component, value);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array(const Array<T, is_scal> & vect,
bool deep,
const ID & id) {
AKANTU_DEBUG_IN();
this->id = (id == "") ? vect.id : id;
if (deep) {
allocate(vect.size, vect.nb_component);
T * tmp = values;
std::uninitialized_copy(vect.storage(), vect.storage() + size * nb_component, tmp);
} else {
this->values = vect.storage();
this->size = vect.size;
this->nb_component = vect.nb_component;
this->allocated_size = vect.allocated_size;
this->size_of_type = vect.size_of_type;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
#ifndef SWIG
template <class T, bool is_scal>
Array<T, is_scal>::Array(const std::vector<T>& vect) {
AKANTU_DEBUG_IN();
this->id = "";
allocate(vect.size(), 1);
T * tmp = values;
std::uninitialized_copy(&(vect[0]), &(vect[size-1]), tmp);
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::~Array () {
AKANTU_DEBUG_IN();
AKANTU_DEBUG(dblAccessory, "Freeing "
<< printMemorySize<T>(allocated_size*nb_component)
<< " (" << id <<")");
if(values){
if(!is_scal)
for (UInt i = 0; i < size * nb_component; ++i) {
T * obj = values+i;
obj->~T();
}
free(values);
}
size = allocated_size = 0;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* perform the allocation for the constructors
* @param size is the size of the array
* @param nb_component is the number of component of the array
*/
template <class T, bool is_scal>
void Array<T, is_scal>::allocate(UInt size,
UInt nb_component) {
AKANTU_DEBUG_IN();
if (size == 0){
values = NULL;
} else {
values = static_cast<T*>(malloc(nb_component * size * sizeof(T)));
AKANTU_DEBUG_ASSERT(values != NULL,
"Cannot allocate "
<< printMemorySize<T>(size*nb_component)
<< " (" << id <<")");
}
if (values == NULL) {
this->size = this->allocated_size = 0;
} else {
AKANTU_DEBUG(dblAccessory, "Allocated "
<< printMemorySize<T>(size*nb_component)
<< " (" << id <<")");
this->size = this->allocated_size = size;
}
this->size_of_type = sizeof(T);
this->nb_component = nb_component;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* change the size of the array and allocate or free memory if needed. If the
* size increases, the new tuples are filled with zeros
* @param new_size new number of tuples contained in the array */
template <class T, bool is_scal>
void Array<T, is_scal>::resize(UInt new_size) {
UInt old_size = size;
T * old_values = values;
if(new_size < size) {
for (UInt i = new_size * nb_component; i < size * nb_component; ++i) {
T * obj = old_values+i;
obj->~T();
}
}
resizeUnitialized(new_size);
T val = T();
if(size > old_size)
std::uninitialized_fill(values + old_size*nb_component, values + size*nb_component, val);
}
/* -------------------------------------------------------------------------- */
/**
* change the size of the array and allocate or free memory if needed.
* @param new_size new number of tuples contained in the array */
template <class T, bool is_scal>
void Array<T, is_scal>::resizeUnitialized(UInt new_size) {
// AKANTU_DEBUG_IN();
// free some memory
if(new_size <= allocated_size) {
if(allocated_size - new_size > AKANTU_MIN_ALLOCATION) {
AKANTU_DEBUG(dblAccessory, "Freeing "
<< printMemorySize<T>((allocated_size - size)*nb_component)
<< " (" << id <<")");
// Normally there are no allocation problem when reducing an array
T * tmp_ptr = static_cast<T*>(realloc(values, new_size * nb_component * sizeof(T)));
if(new_size != 0 && tmp_ptr == NULL) {
AKANTU_DEBUG_ERROR("Cannot free data (" << id << ")"
<< " [current allocated size : " << allocated_size << " | "
<< "requested size : " << new_size << "]");
}
values = tmp_ptr;
allocated_size = new_size;
}
size = new_size;
// AKANTU_DEBUG_OUT();
return;
}
// allocate more memory
UInt size_to_alloc = (new_size - allocated_size < AKANTU_MIN_ALLOCATION) ?
allocated_size + AKANTU_MIN_ALLOCATION : new_size;
T *tmp_ptr = static_cast<T*>(realloc(values, size_to_alloc * nb_component * sizeof(T)));
AKANTU_DEBUG_ASSERT(tmp_ptr != NULL,
"Cannot allocate "
<< printMemorySize<T>(size_to_alloc * nb_component));
if (tmp_ptr == NULL) {
AKANTU_DEBUG_ERROR("Cannot allocate more data (" << id << ")"
<< " [current allocated size : " << allocated_size << " | "
<< "requested size : " << new_size << "]");
}
AKANTU_DEBUG(dblAccessory, "Allocating "
<< printMemorySize<T>((size_to_alloc - allocated_size)*nb_component));
allocated_size = size_to_alloc;
size = new_size;
values = tmp_ptr;
// AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* change the number of components by interlacing data
* @param multiplicator number of interlaced components add
* @param block_size blocks of data in the array
* Examaple for block_size = 2, multiplicator = 2
* array = oo oo oo -> new array = oo nn nn oo nn nn oo nn nn */
template <class T, bool is_scal>
void Array<T, is_scal>::extendComponentsInterlaced(UInt multiplicator,
UInt block_size) {
AKANTU_DEBUG_IN();
if (multiplicator == 1) return;
AKANTU_DEBUG_ASSERT(multiplicator > 1,
"invalid multiplicator");
AKANTU_DEBUG_ASSERT(nb_component%block_size == 0,
"stride must divide actual number of components");
values = static_cast<T*>(realloc(values, nb_component*multiplicator*size* sizeof(T)));
UInt new_component = nb_component/block_size * multiplicator;
for (UInt i = 0,k=size-1; i < size; ++i,--k) {
for (UInt j = 0; j < new_component; ++j) {
UInt m = new_component - j -1;
UInt n = m/multiplicator;
for (UInt l = 0,p=block_size-1; l < block_size; ++l,--p) {
values[k*nb_component*multiplicator+m*block_size+p] =
values[k*nb_component+n*block_size+p];
}
}
}
nb_component = nb_component * multiplicator;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* search elem in the array, return the position of the first occurrence or
* -1 if not found
* @param elem the element to look for
* @return index of the first occurrence of elem or -1 if elem is not present
*/
template <class T, bool is_scal>
Int Array<T, is_scal>::find(const T & elem) const {
AKANTU_DEBUG_IN();
UInt i = 0;
for (; (i < size) && (values[i] != elem); ++i);
AKANTU_DEBUG_OUT();
return (i == size) ? -1 : (Int) i;
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Int Array<T, is_scal>::find(T elem[]) const {
AKANTU_DEBUG_IN();
T * it = values;
UInt i = 0;
for (;i < size; ++i) {
if(*it == elem[0]) {
T * cit = it;
UInt c = 0;
for(; (c < nb_component) && (*cit == elem[c]); ++c, ++cit);
if(c == nb_component) {
AKANTU_DEBUG_OUT();
return i;
}
}
it += nb_component;
}
return -1;
}
/* -------------------------------------------------------------------------- */
/**
* copy the content of another array. This overwrites the current content.
* @param other Array to copy into this array. It has to have the same
* nb_component as this. If compiled in debug mode, an incorrect other will
* result in an exception being thrown. Optimised code may result in
* unpredicted behaviour.
*/
template <class T, bool is_scal>
void Array<T, is_scal>::copy(const Array<T, is_scal>& vect, bool no_sanity_check) {
AKANTU_DEBUG_IN();
if(!no_sanity_check)
if(vect.nb_component != nb_component)
AKANTU_DEBUG_ERROR("The two arrays do not have the same number of components");
resize((vect.size * vect.nb_component) / nb_component);
T * tmp = values;
std::uninitialized_copy(vect.storage(), vect.storage() + size * nb_component, tmp);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<bool is_scal>
class ArrayPrintHelper {
public:
template<typename T>
static void print_content(const Array<T> & vect, std::ostream & stream, int indent) {
if(AKANTU_DEBUG_TEST(dblDump) || AKANTU_DEBUG_LEVEL_IS_TEST()) {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << " + values : {";
for (UInt i = 0; i < vect.getSize(); ++i) {
stream << "{";
for (UInt j = 0; j < vect.getNbComponent(); ++j) {
stream << vect(i, j);
if(j != vect.getNbComponent() - 1) stream << ", ";
}
stream << "}";
if(i != vect.getSize() - 1) stream << ", ";
}
stream << "}" << std::endl;
}
}
};
template<>
class ArrayPrintHelper<false> {
public:
template<typename T>
static void print_content(__attribute__((unused)) const Array<T> & vect,
__attribute__((unused)) std::ostream & stream,
__attribute__((unused)) int indent) { }
};
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
void Array<T, is_scal>::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
std::streamsize prec = stream.precision();
std::ios_base::fmtflags ff = stream.flags();
stream.setf (std::ios_base::showbase);
stream.precision(2);
stream << space << "Array<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
stream << space << " + id : " << this->id << std::endl;
stream << space << " + size : " << this->size << std::endl;
stream << space << " + nb_component : " << this->nb_component << std::endl;
stream << space << " + allocated size : " << this->allocated_size << std::endl;
stream << space << " + memory size : "
<< printMemorySize<T>(allocated_size*nb_component) << std::endl;
if(!AKANTU_DEBUG_LEVEL_IS_TEST())
stream << space << " + address : " << std::hex << this->values
<< std::dec << std::endl;
stream.precision(prec);
stream.flags(ff);
ArrayPrintHelper<is_scal>::print_content(*this, stream, indent);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
/* Inline Functions ArrayBase */
/* -------------------------------------------------------------------------- */
inline UInt ArrayBase::getMemorySize() const {
return allocated_size * nb_component * size_of_type;
}
inline void ArrayBase::empty() {
size = 0;
}
/* -------------------------------------------------------------------------- */
/* Iterators */
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template<class R, class IR, bool is_r_scal>
class Array<T, is_scal>::iterator_internal {
public:
typedef R value_type;
typedef R* pointer;
typedef R& reference;
typedef typename R::proxy proxy;
typedef const typename R::proxy const_proxy;
typedef const R& const_reference;
typedef IR internal_value_type;
typedef IR* internal_pointer;
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
public:
iterator_internal() : _offset(0), initial(NULL), ret(NULL), ret_ptr(NULL) {};
iterator_internal(pointer_type data, UInt _offset) :
_offset(_offset),
initial(data),
ret(NULL),
ret_ptr(data) {
AKANTU_DEBUG_ERROR("The constructor should never be called it is just an ugly trick...");
}
iterator_internal(pointer wrapped) : _offset(wrapped->size()),
initial(wrapped->storage()),
ret(const_cast<internal_pointer>(wrapped)),
ret_ptr(wrapped->storage()) {
}
iterator_internal(const iterator_internal & it) {
if(this != &it) {
this->_offset = it._offset;
this->initial = it.initial;
this->ret_ptr = it.ret_ptr;
this->ret = new internal_value_type(*it.ret, false);
}
}
virtual ~iterator_internal() { delete ret; };
inline iterator_internal & operator=(const iterator_internal & it) {
if(this != &it) {
this->_offset = it._offset;
this->initial = it.initial;
this->ret_ptr = it.ret_ptr;
if(this->ret) this->ret->shallowCopy(*it.ret);
else this->ret = new internal_value_type(*it.ret, false);
}
return *this;
}
UInt getCurrentIndex(){return (this->ret_ptr - this->initial)/this->_offset;};
inline reference operator*() { ret->values = ret_ptr; return *ret; };
inline const_reference operator*() const { ret->values = ret_ptr; return *ret; };
inline pointer operator->() { ret->values = ret_ptr; return ret; };
inline iterator_internal & operator++() { ret_ptr += _offset; return *this; };
inline iterator_internal & operator--() { ret_ptr -= _offset; return *this; };
inline iterator_internal & operator+=(const UInt n) { ret_ptr += _offset * n; return *this; }
inline iterator_internal & operator-=(const UInt n) { ret_ptr -= _offset * n; return *this; }
inline proxy operator[](const UInt n) { ret->values = ret_ptr + n*_offset; return proxy(*ret); }
inline const_proxy operator[](const UInt n) const { ret->values = ret_ptr + n*_offset; return const_proxy(*ret); }
inline bool operator==(const iterator_internal & other) const { return this->ret_ptr == other.ret_ptr; }
inline bool operator!=(const iterator_internal & other) const { return this->ret_ptr != other.ret_ptr; }
inline bool operator <(const iterator_internal & other) const { return this->ret_ptr < other.ret_ptr; }
inline bool operator<=(const iterator_internal & other) const { return this->ret_ptr <= other.ret_ptr; }
inline bool operator> (const iterator_internal & other) const { return this->ret_ptr > other.ret_ptr; }
inline bool operator>=(const iterator_internal & other) const { return this->ret_ptr >= other.ret_ptr; }
inline iterator_internal operator+(difference_type n) { iterator_internal tmp(*this); tmp += n; return tmp; }
inline iterator_internal operator-(difference_type n) { iterator_internal tmp(*this); tmp -= n; return tmp; }
inline difference_type operator-(const iterator_internal & b) { return (this->ret_ptr - b.ret_ptr) / _offset; }
inline pointer_type data() const { return ret_ptr; }
inline difference_type offset() const { return _offset; }
protected:
UInt _offset;
pointer_type initial;
internal_pointer ret;
pointer_type ret_ptr;
};
/* -------------------------------------------------------------------------- */
/**
* Specialization for scalar types
*/
template <class T, bool is_scal>
template <class R, class IR>
class Array<T, is_scal>::iterator_internal<R, IR, true> {
public:
typedef R value_type;
typedef R* pointer;
typedef R& reference;
typedef const R& const_reference;
typedef IR internal_value_type;
typedef IR* internal_pointer;
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
public:
iterator_internal(pointer data = NULL, __attribute__ ((unused)) UInt _offset = 1) : _offset(_offset), ret(data), initial(data) { };
iterator_internal(const iterator_internal & it) {
if(this != &it) { this->ret = it.ret; this->initial = it.initial; }
}
virtual ~iterator_internal() { };
inline iterator_internal & operator=(const iterator_internal & it)
{ if(this != &it) { this->ret = it.ret; this->initial = it.initial; } return *this; }
UInt getCurrentIndex(){return (this->ret - this->initial)/this->_offset;};
inline reference operator*() { return *ret; };
inline const_reference operator*() const { return *ret; };
inline pointer operator->() { return ret; };
inline iterator_internal & operator++() { ++ret; return *this; };
inline iterator_internal & operator--() { --ret; return *this; };
inline iterator_internal & operator+=(const UInt n) { ret += n; return *this; }
inline iterator_internal & operator-=(const UInt n) { ret -= n; return *this; }
inline reference operator[](const UInt n) { return ret[n]; }
inline bool operator==(const iterator_internal & other) const { return ret == other.ret; }
inline bool operator!=(const iterator_internal & other) const { return ret != other.ret; }
inline bool operator< (const iterator_internal & other) const { return ret < other.ret; }
inline bool operator<=(const iterator_internal & other) const { return ret <= other.ret; }
inline bool operator> (const iterator_internal & other) const { return ret > other.ret; }
inline bool operator>=(const iterator_internal & other) const { return ret >= other.ret; }
inline iterator_internal operator-(difference_type n) { return iterator_internal(ret - n); }
inline iterator_internal operator+(difference_type n) { return iterator_internal(ret + n); }
inline difference_type operator-(const iterator_internal & b) { return ret - b.ret; }
inline pointer data() const { return ret; }
inline difference_type offset() const { return _offset; }
protected:
difference_type _offset;
pointer ret;
pointer initial;
};
/* -------------------------------------------------------------------------- */
/* Begin/End functions implementation */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Vector<T> * to the
* first tuple of the array.
* @param n vector size. Has to be equal to nb_component. This unfortunate
* redundancy is necessary to distinguish it from ::begin() which it
* overloads. If compiled in debug mode, an incorrect value of n will result
* in an exception being thrown. Optimized code will fail in an unpredicted
* manner.
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::vector_iterator Array<T, is_scal>::begin(UInt n) {
AKANTU_DEBUG_ASSERT(nb_component == n,
"The iterator is not compatible with the type Array("
<< n<< ")");
return vector_iterator(new Vector<T>(values, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Vector<T> * pointing
* *past* the last tuple of the array.
* @param n vector size. see Array::begin(UInt n) for more
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::vector_iterator Array<T, is_scal>::end(UInt n) {
AKANTU_DEBUG_ASSERT(nb_component == n,
"The iterator is not compatible with the type Array("
<< n<< ")");
return vector_iterator(new Vector<T>(values + nb_component * size,
n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Vector<T> * to the
* first tuple of the array.
* @param n vector size. see Array::begin(UInt n) for more
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_vector_iterator Array<T, is_scal>::begin(UInt n) const {
AKANTU_DEBUG_ASSERT(nb_component == n,
"The iterator is not compatible with the type Array("
<< n<< ")");
return const_vector_iterator(new Vector<T>(values, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Vector<T> * pointing
* *past* the last tuple of the array.
* @param n vector size. see Array::begin(UInt n) for more
* @return a const_vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_vector_iterator Array<T, is_scal>::end(UInt n) const {
AKANTU_DEBUG_ASSERT(nb_component == n,
"The iterator is not compatible with the type Array("
<< n<< ")");
return const_vector_iterator(new Vector<T>(values + nb_component * size,
n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Vector<T> * to the
* first tuple of the array.
*
* The reinterpret iterators allow to iterate over an array in any way that
* preserves the number of entries of the array. This can for instance be use
* full if the shape of the data in an array is not initially known.
* @param n vector size.
* @param size number of tuples in array. n times size must match the number
* of entries of the array. If compiled in debug mode, an incorrect
* combination of n and size will result
* in an exception being thrown. Optimized code will fail in an unpredicted
* manner.
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::vector_iterator
Array<T, is_scal>::begin_reinterpret(UInt n, __attribute__((unused)) UInt size) {
AKANTU_DEBUG_ASSERT(n * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return vector_iterator(new Vector<T>(values, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Vector<T> * pointing
* *past* the last tuple of the array.
* @param n vector size.
* @param size number of tuples in array. See Array::begin_reinterpret(UInt n, UInt size)
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::vector_iterator
Array<T, is_scal>::end_reinterpret(UInt n, UInt size) {
AKANTU_DEBUG_ASSERT(n * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return vector_iterator(new Vector<T>(values + n * size, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Vector<T> * to the
* first tuple of the array.
* @param n vector size.
* @param size number of tuples in array. See Array::begin_reinterpret(UInt n, UInt size)
* @return a const_vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_vector_iterator
Array<T, is_scal>::begin_reinterpret(UInt n, __attribute__((unused)) UInt size) const {
AKANTU_DEBUG_ASSERT(n * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_vector_iterator(new Vector<T>(values, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Vector<T> * pointing
* *past* the last tuple of the array.
* @param n vector size.
* @param size number of tuples in array. See Array::begin_reinterpret(UInt n, UInt size)
* @return a const_vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_vector_iterator
Array<T, is_scal>::end_reinterpret(UInt n, UInt size) const {
AKANTU_DEBUG_ASSERT(n * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_vector_iterator(new Vector<T>(values + n * size, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Matrix<T> * to the
* first tuple of the array.
* @param m number of rows
* @param n number of columns. m times n has to equal nb_component.
* If compiled in debug mode, an incorrect combination of m and n will result
* in an exception being thrown. Optimized code will fail in an unpredicted
* manner.
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::matrix_iterator Array<T, is_scal>::begin(UInt m, UInt n) {
AKANTU_DEBUG_ASSERT(nb_component == n*m,
"The iterator is not compatible with the type Matrix("
<< m << "," << n<< ")");
return matrix_iterator(new Matrix<T>(values, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Matrix<T> * pointing
* *past* the last tuple of the array.
* @param m number of rows
* @param n number of columns. See Array::begin(UInt m, UInt n)
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::matrix_iterator Array<T, is_scal>::end(UInt m, UInt n) {
AKANTU_DEBUG_ASSERT(nb_component == n*m,
"The iterator is not compatible with the type Matrix("
<< m << "," << n<< ")");
return matrix_iterator(new Matrix<T>(values + nb_component * size, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Matrix<T> * to the
* first tuple of the array.
* @param m number of rows
* @param n number of columns. See Array::begin(UInt m, UInt n)
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_matrix_iterator Array<T, is_scal>::begin(UInt m, UInt n) const {
AKANTU_DEBUG_ASSERT(nb_component == n*m,
"The iterator is not compatible with the type Matrix("
<< m << "," << n<< ")");
return const_matrix_iterator(new Matrix<T>(values, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Matrix<T> * pointing
* *past* the last tuple of the array.
* @param m number of rows
* @param n number of columns. See Array::begin(UInt m, UInt n)
* @return a const_matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_matrix_iterator Array<T, is_scal>::end(UInt m, UInt n) const {
AKANTU_DEBUG_ASSERT(nb_component == n*m,
"The iterator is not compatible with the type Matrix("
<< m << "," << n<< ")");
return const_matrix_iterator(new Matrix<T>(values + nb_component * size, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Matrix<T> * to the
* first tuple of the array.
*
* The reinterpret iterators allow to iterate over an array in any way that
* preserves the number of entries of the array. This can for instance be use
* full if the shape of the data in an array is not initially known.
* @param m number of rows
* @param n number of columns
* @param size number of tuples in array. m times n times size must match the number
* of entries of the array. If compiled in debug mode, an incorrect
* combination of m, n and size will result
* in an exception being thrown. Optimized code will fail in an unpredicted
* manner.
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::matrix_iterator
Array<T, is_scal>::begin_reinterpret(UInt m, UInt n, __attribute__((unused)) UInt size) {
AKANTU_DEBUG_ASSERT(n * m * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << m << "," << n << " = " << n * m
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return matrix_iterator(new Matrix<T>(values, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Matrix<T> * pointing
* *past* the last tuple of the array.
* @param m number of rows
* @param n number of columns
* @param size number of tuples in array. See Array::begin_reinterpret(UInt m, UInt n, UInt size)
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::matrix_iterator
Array<T, is_scal>::end_reinterpret(UInt m, UInt n, UInt size) {
AKANTU_DEBUG_ASSERT(n * m * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << m << "," << n << " = " << n * m
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return matrix_iterator(new Matrix<T>(values + n * m * size, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Matrix<T> * to the
* first tuple of the array.
* @param m number of rows
* @param n number of columns
* @param size number of tuples in array. See Array::begin_reinterpret(UInt m, UInt n, UInt size)
* @return a const_matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_matrix_iterator
Array<T, is_scal>::begin_reinterpret(UInt m, UInt n, __attribute__((unused)) UInt size) const {
AKANTU_DEBUG_ASSERT(n * m * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << m << "," << n << " = " << n * m
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_matrix_iterator(new Matrix<T>(values, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Matrix<T> * pointing
* *past* the last tuple of the array.
* @param m number of rows
* @param n number of columns
* @param size number of tuples in array. See Array::begin_reinterpret(UInt m, UInt n, UInt size)
* @return a const_matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_matrix_iterator
Array<T, is_scal>::end_reinterpret(UInt m, UInt n, UInt size) const {
AKANTU_DEBUG_ASSERT(n * m * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << m << "," << n << " = " << n * m
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_matrix_iterator(new Matrix<T>(values + n * m * size, m, n));
}
/* -------------------------------------------------------------------------- */
/** Get an iterator that behaves like a pointer T * to the
* first entry in the member array values
* @return a scalar_iterator
*/
template <class T, bool is_scal>
inline Array<T, is_scal>::iterator<T> Array<T, is_scal>::begin() {
AKANTU_DEBUG_ASSERT(nb_component == 1, "this iterator cannot be used on a vector which has nb_component != 1");
return iterator<T>(values);
}
/* -------------------------------------------------------------------------- */
/*! Get an iterator that behaves like a pointer T * that points *past* the
* last entry in the member array values
* @return a scalar_iterator
*/
template <class T, bool is_scal>
inline Array<T, is_scal>::iterator<T> Array<T, is_scal>::end() {
AKANTU_DEBUG_ASSERT(nb_component == 1, "this iterator cannot be used on a array which has nb_component != 1");
return iterator<T>(values + size);
}
/* -------------------------------------------------------------------------- */
/*! Get a const iterator that behaves like a pointer T * to the
* first entry in the member array values
* @return a const_scalar_iterator
*/
template <class T, bool is_scal>
inline Array<T, is_scal>::const_iterator<T> Array<T, is_scal>::begin() const {
AKANTU_DEBUG_ASSERT(nb_component == 1, "this iterator cannot be used on a array which has nb_component != 1");
return const_iterator<T>(values);
}
/* -------------------------------------------------------------------------- */
/*! Get a const iterator that behaves like a pointer T * that points *past* the
* last entry in the member array values
* @return a const_scalar_iterator
*/
template <class T, bool is_scal>
inline Array<T, is_scal>::const_iterator<T> Array<T, is_scal>::end() const {
AKANTU_DEBUG_ASSERT(nb_component == 1, "this iterator cannot be used on a array which has nb_component != 1");
return const_iterator<T>(values + size);
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template<typename R>
class Array<T, is_scal>::const_iterator : public iterator_internal<const R, R> {
public:
typedef iterator_internal<const R, R> parent;
typedef typename parent::value_type value_type;
typedef typename parent::pointer pointer;
typedef typename parent::reference reference;
typedef typename parent::difference_type difference_type;
typedef typename parent::iterator_category iterator_category;
public:
const_iterator() : parent() {};
const_iterator(pointer_type data, UInt offset) : parent(data, offset) {}
const_iterator(pointer warped) : parent(warped) {}
const_iterator(const parent & it) : parent(it) {}
// const_iterator(const const_iterator<R> & it) : parent(it) {}
inline const_iterator operator+(difference_type n)
{ return parent::operator+(n); }
inline const_iterator operator-(difference_type n)
{ return parent::operator-(n); }
inline difference_type operator-(const const_iterator & b)
{ return parent::operator-(b); }
inline const_iterator & operator++()
{ parent::operator++(); return *this; };
inline const_iterator & operator--()
{ parent::operator--(); return *this; };
inline const_iterator & operator+=(const UInt n)
{ parent::operator+=(n); return *this; }
};
// #endif
// #if defined(AKANTU_CORE_CXX11)
// template<class R> using iterator = iterator_internal<R>;
// #else
template < class T, class R, bool issame = is_same<T, R>::value >
struct ConstConverterIteratorHelper {
typedef typename Array<T>::template const_iterator<R> const_iterator;
typedef typename Array<T>::template iterator<R> iterator;
static inline const_iterator convert(const iterator & it) {
return const_iterator(new R(*it, false));
}
};
template < class T, class R >
struct ConstConverterIteratorHelper<T, R, true> {
typedef typename Array<T>::template const_iterator<R> const_iterator;
typedef typename Array<T>::template iterator<R> iterator;
static inline const_iterator convert(const iterator & it) {
return const_iterator(it.data(), it.offset());
}
};
template <class T, bool is_scal>
template<typename R>
class Array<T, is_scal>::iterator : public iterator_internal<R> {
public:
typedef iterator_internal<R> parent;
typedef typename parent::value_type value_type;
typedef typename parent::pointer pointer;
typedef typename parent::reference reference;
typedef typename parent::difference_type difference_type;
typedef typename parent::iterator_category iterator_category;
public:
iterator() : parent() {};
iterator(pointer_type data, UInt offset) : parent(data, offset) {};
iterator(pointer warped) : parent(warped) {}
iterator(const parent & it) : parent(it) {}
// iterator(const iterator<R> & it) : parent(it) {}
operator const_iterator<R>() {
return ConstConverterIteratorHelper<T, R>::convert(*this);
}
inline iterator operator+(difference_type n)
{ return parent::operator+(n);; }
inline iterator operator-(difference_type n)
{ return parent::operator-(n);; }
inline difference_type operator-(const iterator & b)
{ return parent::operator-(b); }
inline iterator & operator++()
{ parent::operator++(); return *this; };
inline iterator & operator--()
{ parent::operator--(); return *this; };
inline iterator & operator+=(const UInt n)
{ parent::operator+=(n); return *this; }
};
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template<typename R>
inline Array<T, is_scal>::iterator<R> Array<T, is_scal>::erase(const iterator<R> & it) {
T * curr = it.data();
UInt pos = (curr - values) / nb_component;
erase(pos);
iterator<R> rit = it;
return --rit;
}
// #endif
diff --git a/src/common/aka_ball.cc b/src/common/aka_ball.cc
index 616e0ffd3..2e9993678 100644
--- a/src/common/aka_ball.cc
+++ b/src/common/aka_ball.cc
@@ -1,73 +1,74 @@
/**
* @file aka_ball.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Tue May 07 2013
- * @date last modification: Tue May 07 2013
+ * @date creation: Sun Sep 26 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief bounding sphere classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_ball.hh"
__BEGIN_AKANTU__
template <>
std::ostream& Interval::print(std::ostream& os) const {
os<<"Interval["<<c_<<", "<<r_<<"]";
return os;
}
template <>
std::ostream& Circle::print(std::ostream& os) const {
os<<"Disk["<<c_<<", "<<r_<<"]";
return os;
}
template <>
std::ostream& Sphere::print(std::ostream& os) const {
os<<"Sphere["<<c_<<", "<<r_<<"]";
return os;
}
template <>
typename Ball<1>::value_type Ball<1>::measure() const
{ return r_; }
template <>
typename Ball<2>::value_type Ball<2>::measure() const
{ return pow(r_,2); }
template <>
typename Ball<3>::value_type Ball<3>::measure() const
{ return pow(r_,3); }
__END_AKANTU__
diff --git a/src/common/aka_ball.hh b/src/common/aka_ball.hh
index 049e61b4c..794c5fc68 100644
--- a/src/common/aka_ball.hh
+++ b/src/common/aka_ball.hh
@@ -1,286 +1,286 @@
/**
* @file aka_ball.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue Jun 17 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief bounding ball classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_BALL_HH__
#define __AKANTU_BALL_HH__
#include <iostream>
#include "aka_common.hh"
#include "aka_point.hh"
#include "aka_bounding_box.hh"
__BEGIN_AKANTU__
static Real epsilon = 10*std::numeric_limits<Real>::epsilon();
using std::cout;
using std::endl;
//! Ball class template
/*! This class template represents the abstraction of a d-dimensional sphere.
* \tparam d - Ball dimension
*/
template <int d>
class Ball : public Bounding_volume<d> {
public:
typedef Bounding_volume<d> base_type;
typedef typename base_type::point_type point_type;
typedef typename point_type::value_type value_type;
typedef BoundingBox<d> aabb_type;
//! Return ball dimension
constexpr static int dim()
{ return d; }
//! Parameter constructor takes the ball center point and its radius
Ball(const point_type& c = point_type(), value_type r = value_type()) : base_type(), c_(c), r_(r) {}
//! Combine two ball objects
virtual base_type* combine(const base_type& b) const {
const Ball* sp = dynamic_cast<const Ball*>(&b);
assert(sp != nullptr);
const Ball& s0 = *sp;
Ball r(s0);
r += *this;
return new Ball(r);
}
//! Standard output stream operator
virtual std::ostream& print(std::ostream& os) const;
aabb_type bounding_box() const {
point_type o = r_*point_type(1.);
return aabb_type(c_ - o, c_ + o);
}
//! Get ball center
point_type const& center() const
{ return c_; }
//! Get ball radius
value_type const& radius() const
{ return r_; }
//! Use in generic code as comparative measure of how big the sphere is
value_type measure() const;
//! Grow sphere if point lies outside of it
Ball& operator+=(const point_type& p) {
point_type diff = p - c_;
value_type sq_norm = diff.sq_norm();
if (sq_norm > r_*r_) {
value_type norm = sqrt(sq_norm);
value_type new_r = 0.5*(r_ + norm);
value_type scalar = (new_r - r_) / norm;
r_ = new_r;
c_ += scalar * diff;
}
return *this;
}
//! Determine the ball that encloses both spheres
Ball& operator+=(const Ball s) {
point_type diff = s.c_ - c_;
value_type sq_norm = diff.sq_norm();
// one ball is contained within the other
if (pow(s.r_ - r_, 2) >= sq_norm) {
if(s.r_ >= r_)
this->operator=(s);
// else do nothing, as the current ball is bigger
// and no further changes are required
}
// else balls partially overlapping or disjoint
else {
// compute new radius
value_type norm = sqrt(sq_norm);
value_type tmp = r_;
r_ = 0.5 * (norm + r_ + s.r_);
if (norm > epsilon)
c_ += ((r_ - tmp) / norm) * diff;
}
return *this;
}
//! Check for collision with a point
bool operator&(const point_type& p) const
{ return (p - c_).sq_norm() - r_*r_ < epsilon; }
//! Check for collision with another ball
bool operator&(const Ball& s) const
{ return (c_ - s.c_).sq_norm() - pow(r_ + s.r_,2.) < epsilon; }
//! Compute ball from intersection of bounding boxes of two balls
Ball operator&&(const Ball& b) const {
// get bounding boxes of spheres
aabb_type bb1 = bounding_box();
aabb_type bb2 = b.bounding_box();
// compute intersection
aabb_type bbint = bb1 && bb2;
// compute center and radius of the sphere
point_type c = 0.5*(bbint.min() + bbint.max());
value_type r = sqrt((bbint.min() - bbint.max()).sq_norm());
// construct sphere
return Ball(c,r);
}
private:
point_type c_; //!< Ball center
Real r_; //!< Ball radius
};
//! Interval type definition
typedef Ball<1> Interval;
//! Circle type definition
typedef Ball<2> Circle;
//! Sphere type definition
typedef Ball<3> Sphere;
//! Add two balls
template <int d>
Ball<d> operator+(const Ball<d>& s1, const Ball<d>& s2) {
Ball<d> r(s1);
return r += s2;
}
//! Extreme points algirhtm by Ritter
/*! J. Ritter, Graphics gems, Academic Press Professional, Inc., San Diego, CA, USA, 1990, Ch.
* An efficient bounding sphere, pp. 301–303. URL http://dl.acm.org/citation.cfm?id=90767.90836
*/
template <class point_container>
std::pair<size_t, size_t> extreme_points(const point_container& pts) {
typedef typename point_container::value_type point_type;
typedef typename point_type::value_type value_type;
size_t min[] = { 0, 0, 0 };
size_t max[] = { 0, 0, 0 };
// loop over container points to find extremal points
for (size_t i=1; i<pts.size(); ++i) {
const point_type& p = pts[i];
// loop over coordinates
for (int j=0; j<point_type::dim(); ++j) {
// check if new point is minimum
if (p[j] < pts[min[j]][j])
min[j] = i;
// check if new point is maximum
else if (p[j] > pts[max[j]][j])
max[j] = i;
}
}
// pick the pair of the longest distance
size_t m=0, M=0;
value_type sq_norm = value_type();
for (int i=0; i<point_type::dim(); ++i) {
point_type diff = pts[max[i]] - pts[min[i]];
value_type new_sq_norm = diff.sq_norm();
if (new_sq_norm > sq_norm) {
m = min[i];
M = max[i];
sq_norm = new_sq_norm;
}
}
return std::make_pair(m,M);
}
//! Create a bounding ball from a container of points
template <int d, class point_container>
Ball<d> bounding_ball(const point_container& pts) {
assert(!pts.empty());
typedef typename point_container::value_type point_type;
typedef typename point_type::value_type value_type;
// find extreme points on axis-aligned bounding box to construct
// first approximation of the sphere
std::pair<size_t, size_t> mM = extreme_points(pts);
// compute center and radius of the sphere
const point_type &m = pts[mM.first];
const point_type &M = pts[mM.second];
point_type c = 0.5*(m+M);
value_type r = sqrt((M-c).sq_norm());
// construct sphere
Ball<d> s(c,r);
// second pass: update the sphere so that all points lie inside
for (size_t i=0; i<pts.size(); ++i)
s += pts[i];
return s;
}
__END_AKANTU__
#endif /* __AKANTU_BALL_HH__ */
diff --git a/src/common/aka_blas_lapack.hh b/src/common/aka_blas_lapack.hh
index 201a5b95f..030a8693f 100644
--- a/src/common/aka_blas_lapack.hh
+++ b/src/common/aka_blas_lapack.hh
@@ -1,324 +1,324 @@
/**
* @file aka_blas_lapack.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Mar 06 2013
- * @date last modification: Tue Jun 24 2014
+ * @date last modification: Thu Dec 17 2015
*
* @brief Interface of the Fortran BLAS/LAPACK libraries
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_BLAS_LAPACK_HH__
#define __AKANTU_AKA_BLAS_LAPACK_HH__
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_USE_BLAS) || defined(AKANTU_USE_LAPACK)
# include "aka_fortran_mangling.hh"
#endif //AKANTU_USE_BLAS
#ifdef AKANTU_USE_BLAS
extern "C" {
/* ------------------------------------------------------------------------ */
/* Double precision */
/* ------------------------------------------------------------------------ */
//LEVEL 1
double AKA_FC_GLOBAL(ddot, DDOT)(int *, double *, int *, double *, int *);
//LEVEL 2
void AKA_FC_GLOBAL(dgemv, DGEMV)(char *, int *, int *, double *, double *, int *,
double *, int *, double *, double *, int *);
//LEVEL 3
void AKA_FC_GLOBAL(dgemm, DGEMM)(char *, char *, int *, int *, int *, double *,
double *, int *, double *, int *, double *,
double *, int *);
/* ------------------------------------------------------------------------ */
/* Simple precision */
/* ------------------------------------------------------------------------ */
//LEVEL 1
float AKA_FC_GLOBAL(sdot, SDOT)(int *, float *, int *, float *, int *);
//LEVEL 2
void AKA_FC_GLOBAL(sgemv, SGEMV)(char *, int *, int *, float *, float *, int *,
float *, int *, float *, float *, int *);
//LEVEL 3
void AKA_FC_GLOBAL(sgemm, SGEMM)(char *, char *, int *, int *, int *, float *,
float *, int *, float *, int *, float *,
float *, int *);
}
#endif
__BEGIN_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(__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"
#endif
/// Wrapper around the S/DDOT BLAS function that returns the dot product of two vectors
template<typename T>
inline T aka_dot(int *n, T *x, int *incx, T *y, int *incy) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated BLAS in the compilation options!");
}
/// Wrapper around the S/DGEMV BLAS function that computes matrix-vector product \f$y := \alpha A^{(T)}x + \beta y \f$
template<typename T>
inline void aka_gemv(char *trans, int *m, int *n, T *
alpha, T *a, int *lda, T *x, int *incx,
T *beta, T *y, int *incy) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated BLAS in the compilation options!");
}
/// Wrapper around the S/DGEMM BLAS function that computes the product of two matrices \f$C := \alpha A^{(T)} B^{(T)} + \beta C \f$
template<typename T>
inline void aka_gemm(char *transa, char *transb,
int *m, int *n, int *k,
T *alpha, T *a, int *lda,
T *b, int *ldb,
T *beta, T *c, int *ldc) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated BLAS in the compilation options!");
}
#if defined(AKANTU_USE_BLAS)
template<>
inline double aka_dot<double>(int *n, double *x, int *incx, double *y, int *incy) {
return AKA_FC_GLOBAL(ddot, DDOT)(n, x, incx, y, incy);
}
template<>
inline void aka_gemv<double>(char *trans, int *m, int *n, double *
alpha, double *a, int *lda, double *x, int *incx,
double *beta, double *y, int *incy) {
return AKA_FC_GLOBAL(dgemv, DGEMV)(trans, m, n, alpha, a, lda, x, incx,
beta, y, incy);
}
template<>
inline void aka_gemm<double>(char *transa, char *transb,
int *m, int *n, int *k,
double *alpha, double *a, int *lda,
double *b, int *ldb,
double *beta, double *c, int *ldc) {
AKA_FC_GLOBAL(dgemm, DGEMM)(transa, transb, m, n, k, alpha, a, lda,
b, ldb, beta, c, ldc);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<>
inline float aka_dot<float>(int *n, float *x, int *incx, float *y, int *incy) {
return AKA_FC_GLOBAL(sdot, SDOT)(n, x, incx, y, incy);
}
template<>
inline void aka_gemv<float>(char *trans, int *m, int *n, float *
alpha, float *a, int *lda, float *x, int *incx,
float *beta, float *y, int *incy) {
AKA_FC_GLOBAL(sgemv, SGEMV)(trans, m, n, alpha, a, lda, x, incx,
beta, y, incy);
}
template<>
inline void aka_gemm<float>(char *transa, char *transb,
int *m, int *n, int *k,
float *alpha, float *a, int *lda,
float *b, int *ldb,
float *beta, float *c, int *ldc) {
AKA_FC_GLOBAL(sgemm, SGEMM)(transa, transb, m, n, k, alpha, a, lda,
b, ldb, beta, c, ldc);
}
#endif
__END_AKANTU__
#ifdef AKANTU_USE_LAPACK
extern "C" {
/* ------------------------------------------------------------------------ */
/* Double general matrix */
/* ------------------------------------------------------------------------ */
/// compute the eigenvalues/vectors
void AKA_FC_GLOBAL(dgeev, DGEEV)(char* jobvl, char* jobvr, int* n, double* a,
int* lda, double* wr, double* wi, double* vl, int* ldvl,
double* vr, int* ldvr, double* work, int* lwork, int* info);
/// LU decomposition of a general matrix
void AKA_FC_GLOBAL(dgetrf, DGETRF)(int* m, int *n,
double* a, int* lda,
int* ipiv, int* info);
/// generate inverse of a matrix given its LU decomposition
void AKA_FC_GLOBAL(dgetri, DGETRI)(int* n, double* a, int* lda,
int* ipiv, double* work, int* lwork, int* info);
/// solving A x = b using a LU factorization
void AKA_FC_GLOBAL(dgetrs, DGETRS)(char * trans, int * n, int * nrhs,
double * A, int * lda, int * ipiv,
double * b, int * ldb, int * info);
/* ------------------------------------------------------------------------ */
/* Simple general matrix */
/* ------------------------------------------------------------------------ */
/// compute the eigenvalues/vectors
void AKA_FC_GLOBAL(sgeev, SGEEV)(char* jobvl, char* jobvr, int* n, float* a,
int* lda, float* wr, float* wi, float* vl, int* ldvl,
float* vr, int* ldvr, float* work, int* lwork, int* info);
/// LU decomposition of a general matrix
void AKA_FC_GLOBAL(sgetrf, SGETRF)(int* m, int *n,
float* a, int* lda,
int* ipiv, int* info);
/// generate inverse of a matrix given its LU decomposition
void AKA_FC_GLOBAL(sgetri, SGETRI)(int* n, float* a, int* lda,
int* ipiv, float* work, int* lwork, int* info);
/// solving A x = b using a LU factorization
void AKA_FC_GLOBAL(sgetrs, SGETRS)(char * trans, int * n, int * nrhs,
float * A, int * lda, int * ipiv,
float * b, int * ldb, int * info);
}
#endif //AKANTU_USE_LAPACK
__BEGIN_AKANTU__
/// Wrapper around the S/DGEEV BLAS function that computes the eigenvalues and eigenvectors of a matrix
template<typename T>
inline void aka_geev(char* jobvl, char* jobvr, int* n, T* a,
int* lda, T* wr, T* wi, T* vl, int* ldvl,
T* vr, int* ldvr, T* work, int* lwork, int* info) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated LAPACK in the compilation options!");
}
/// Wrapper around the S/DGETRF BLAS function that computes the LU decomposition of a matrix
template<typename T>
inline void aka_getrf(int* m, int *n,
T* a, int* lda,
int* ipiv, int* info) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated LAPACK in the compilation options!");
}
/// Wrapper around the S/DGETRI BLAS function that computes the inverse of a matrix given its LU decomposition
template<typename T>
inline void aka_getri(int* n, T* a, int* lda,
int* ipiv, T* work, int* lwork, int* info) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated LAPACK in the compilation options!");
}
/// Wrapper around the S/DGETRS BLAS function that solves \f$A^{(T)}x = b\f$ using LU decomposition
template<typename T>
inline void aka_getrs(char *trans, int * n, int * nrhs,
T * A, int * lda, int * ipiv,
T * b, int * ldb, int * info) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated LAPACK in the compilation options!");
}
#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"
# endif
#endif
#ifdef AKANTU_USE_LAPACK
template<>
inline void aka_geev<double>(char* jobvl, char* jobvr, int* n, double* a,
int* lda, double* wr, double* wi, double* vl, int* ldvl,
double* vr, int* ldvr, double* work, int* lwork, int* info) {
AKA_FC_GLOBAL(dgeev, DGEEV)(jobvl, jobvr, n, a,
lda, wr, wi, vl, ldvl,
vr, ldvr, work, lwork, info);
}
template<>
inline void aka_getrf<double>(int* m, int *n,
double* a, int* lda,
int* ipiv, int* info) {
AKA_FC_GLOBAL(dgetrf, DGETRF)(m, n, a, lda, ipiv, info);
}
template<>
inline void aka_getri<double>(int* n, double* a, int* lda,
int* ipiv, double* work, int* lwork, int* info) {
AKA_FC_GLOBAL(dgetri, DGETRI)(n, a, lda, ipiv, work, lwork, info);
}
template<>
inline void aka_getrs<double>(char *trans, int * n, int * nrhs,
double * A, int * lda, int * ipiv,
double * b, int * ldb, int * info) {
AKA_FC_GLOBAL(dgetrs, DGETRS)(trans, n, nrhs, A, lda, ipiv, b, ldb, info);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<>
inline void aka_geev<float>(char* jobvl, char* jobvr, int* n, float* a,
int* lda, float* wr, float* wi, float* vl, int* ldvl,
float* vr, int* ldvr, float* work, int* lwork, int* info) {
AKA_FC_GLOBAL(sgeev, SGEEV)(jobvl, jobvr, n, a,
lda, wr, wi, vl, ldvl,
vr, ldvr, work, lwork, info);
}
template<>
inline void aka_getrf<float>(int* m, int *n,
float* a, int* lda,
int* ipiv, int* info) {
AKA_FC_GLOBAL(sgetrf, SGETRF)(m, n, a, lda, ipiv, info);
}
template<>
inline void aka_getri<float>(int* n, float* a, int* lda,
int* ipiv, float* work, int* lwork, int* info) {
AKA_FC_GLOBAL(sgetri, SGETRI)(n, a, lda, ipiv, work, lwork, info);
}
template<>
inline void aka_getrs<float>(char *trans, int * n, int * nrhs,
float * A, int * lda, int * ipiv,
float * b, int * ldb, int * info) {
AKA_FC_GLOBAL(sgetrs, SGETRS)(trans, n, nrhs, A, lda, ipiv, b, ldb, info);
}
#endif
__END_AKANTU__
#endif /* __AKANTU_AKA_BLAS_LAPACK_HH__ */
diff --git a/src/common/aka_bounding_box.cc b/src/common/aka_bounding_box.cc
index cc7597f1e..54164c30b 100644
--- a/src/common/aka_bounding_box.cc
+++ b/src/common/aka_bounding_box.cc
@@ -1,83 +1,83 @@
/**
* @file aka_bounding_box.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Fri Mar 21 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief Implementation of the bounding box class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "aka_bounding_box.hh"
#include "aka_array.hh"
__BEGIN_AKANTU__
template <>
std::ostream& operator<< <1>(std::ostream& os, const BoundingBox<1>& bb) {
os<<"Line["<<bb.min()<<","<<bb.max()<<"]";
return os;
}
template <>
std::ostream& operator<< <2>(std::ostream& os, const BoundingBox<2>& bb) {
os<<"Rectangle["<<bb.min()<<","<<bb.max()<<"]";
return os;
}
template <>
std::ostream& operator<< <3>(std::ostream& os, const BoundingBox<3>& bb) {
os<<"Cuboid["<<bb.min()<<","<<bb.max()<<"]";
return os;
}
/* -------------------------------------------------------------------------- */
template <int dim, class nodes_container>
BoundingBox<dim> createPointList(const nodes_container& nodes, const Array<Real>& coord) {
// AKANTU_DEBUG_ASSERT(nodes.getSize() != 0, "No nodes to create a bounding box with.");
typedef typename nodes_container::const_iterator node_iterator;
node_iterator it = nodes.begin();
assert(it != nodes.end());
BoundingBox<dim> bbox(Point<dim>(&coord(*it),coord.getNbComponent()));
for (++it; it != nodes.end(); ++it) {
//Real * point_coord = &coord(*it);
for (UInt d=0; d<coord.getNbComponent(); ++d) {
;
}
bbox += *it;
}
return bbox;
}
__END_AKANTU__
diff --git a/src/common/aka_bounding_box.hh b/src/common/aka_bounding_box.hh
index 2168215b3..2b2ea8639 100644
--- a/src/common/aka_bounding_box.hh
+++ b/src/common/aka_bounding_box.hh
@@ -1,246 +1,246 @@
/**
* @file aka_bounding_box.hh
*
- * @author David Simon Kammer <david.kammer@epfl.ch>
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Mon Jun 02 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief class for a bounding box
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_BOUNDING_BOX_HH__
#define __AKANTU_AKA_BOUNDING_BOX_HH__
#include <iostream>
#include <iomanip>
#include "aka_common.hh"
#include "aka_point.hh"
__BEGIN_AKANTU__
using std::cout;
using std::endl;
template <int> class BoundingBox;
/// considers bounding box with respect to a list of points and adaptes it
template <int d, class point_container>
BoundingBox<d> computeBoundingBox(const point_container& points) {
typedef typename point_container::const_iterator point_iterator;
point_iterator it = points.begin();
assert(it != points.end());
BoundingBox<d> bbox(*it);
for (++it; it != points.end(); ++it)
bbox += *it;
return bbox;
}
template <int d, class nodes_container>
BoundingBox<d> createPointList(const nodes_container& nodes, const Array<Real>& coord);
template <int d>
class BoundingBox : public Bounding_volume<d> {
public:
typedef Bounding_volume<d> base_type;
typedef typename base_type::point_type point_type;
typedef typename point_type::value_type value_type;
static int dim()
{ return d; }
private:
/// minimum point
point_type min_;
/// maximum point
point_type max_;
public:
/// default constructor, creates an inconsistent bounding box
BoundingBox() : base_type(), min_(inf), max_(-inf) {}
/// point constructor, sets the bounding box to the point
BoundingBox(const point_type& p1) : base_type(), min_(p1), max_(p1) {}
/// two-point constructor, calculates minimum and maximum points
BoundingBox(const point_type& p1, const point_type& p2, bool compute = true)
: base_type(), min_(p1), max_(p2)
{
if (compute)
for (Int i=0; i<d; ++i) {
min_[i] = std::min(p1[i], p2[i]);
max_[i] = std::max(p1[i], p2[i]);
}
}
/// multiple-point constructor, creates a bounding box encompass multiple points
template <class iterator>
BoundingBox(iterator first, iterator last) : base_type(), min_(*first), max_(*first) {
++first;
for (; first != last; ++first)
this->operator+=(*first);
}
/// returns the measure of the bounding box: the measure is the volume of the box
value_type measure() const {
value_type v = 1;
for (int i=0; i<d; ++i)
v *= (max_[i] - min_[i]);
return v;
}
///
bool operator<(const BoundingBox& bbox) const {
return min_ < bbox.min_ || (!(bbox.min_ < min_) && max_ < bbox.max_);
}
/**
returns whether the two bounding boxes have min points with the same coordinates
and max points with the same coordinates
**/
bool operator==(const BoundingBox& bbox) const
{ return min_ == bbox.min_ && max_ == bbox.max_; }
/**
returns whether the two bounding boxes have min points with different coordinates
or max points with different coordinates
**/
bool operator!=(const BoundingBox& bbox) const
{ return !(*this == bbox); }
/// extend the bounding box, if necessary, in order to encompass this additional point
BoundingBox& operator+=(const point_type& point) {
for (Int i=0; i<d; ++i) {
min_[i] = std::min(min_[i], point[i]);
max_[i] = std::max(max_[i], point[i]);
}
return *this;
}
/// extend the bounding box, if necessary, in order to encompass the entire given boundary box
BoundingBox& operator+=(const BoundingBox& bbox) {
this->operator+=(bbox.min_);
this->operator+=(bbox.max_);
return *this;
}
/// is the point p geometrically inside of the bounding box?
bool operator&(const point_type& p) const {
Real e = 2*std::numeric_limits<Real>::epsilon();
for (Int i=0; i<d; ++i)
if (max_[i] < p[i] - e || p[i] < min_[i] - e)
return false;
return true;
}
/// is the bounding box bb geometrically entirely inside of the bounding box?
bool operator&(const BoundingBox& bb) const {
Real e = 2*std::numeric_limits<Real>::epsilon();
for (Int i=0; i<d; ++i) {
if (max_[i] < bb.min_[i] - e || bb.max_[i] < min_[i] - e)
return false;
}
return true;
}
/// create the intersection bounding box
BoundingBox operator&&(const BoundingBox& bb) const {
BoundingBox intersection;
for (Int i=0; i<d; ++i) {
intersection.min_[i] = std::max(min_[i], bb.min_[i]);
intersection.max_[i] = std::min(max_[i], bb.max_[i]);
}
return intersection;
}
/// get the point of the minimum corner
const point_type& min()
{ return min_; }
/// get the point of the maximum corner
const point_type& max()
{ return max_; }
/// get the point of the minimum corner
point_type min() const
{ return min_; }
/// get the point of the maximum corner
point_type max() const
{ return max_; }
/// get minimum coordinate of the bounding box in direction i
Real min(size_t i) const
{ return min_[i]; }
/// get maximum coordinate of the bounding box in direction i
Real max(size_t i) const
{ return max_[i]; }
virtual std::ostream& print(std::ostream& os) const {
os<<*this;
return os;
}
public:
/// directional increase of bounding box (if needed)
void expand(Real coord, UInt dir) {
AKANTU_DEBUG_ASSERT(dir < d, "");
}
};
/// cumulate two bounding boxes and create one encompassing both
template <int d>
BoundingBox<d> operator+(const BoundingBox<d>& b1, const BoundingBox<d>& b2) {
BoundingBox<d> r(b1);
return r += b2;
}
template <int d>
std::ostream& operator<<(std::ostream&, const BoundingBox<d>&);
__END_AKANTU__
#endif /* __AKANTU_AKA_BOUNDING_BOX_HH__ */
diff --git a/src/common/aka_circular_array.hh b/src/common/aka_circular_array.hh
index 5a94c6c9c..af005df7c 100644
--- a/src/common/aka_circular_array.hh
+++ b/src/common/aka_circular_array.hh
@@ -1,139 +1,140 @@
/**
* @file aka_circular_array.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Fri Nov 11 2011
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief class of circular array
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_CIRCULAR_ARRAY_HH__
#define __AKANTU_AKA_CIRCULAR_ARRAY_HH__
/* -------------------------------------------------------------------------- */
#include <typeinfo>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
template<class T>
class CircularArray : protected Array<T> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef typename Array<T>::value_type value_type;
typedef typename Array<T>::reference reference;
typedef typename Array<T>::pointer_type pointer_type;
typedef typename Array<T>::const_reference const_reference;
/// Allocation of a new array with a default value
CircularArray(UInt size, UInt nb_component = 1,
const_reference value = value_type(), const ID & id = "") :
Array<T>(size, nb_component, value, id),
start_position(0),
end_position(size-1) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
};
virtual ~CircularArray() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/**
advance start and end position by one:
the first element is now at the end of the array
**/
inline void makeStep();
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
private:
/* ------------------------------------------------------------------------ */
/* Operators */
/* ------------------------------------------------------------------------ */
public:
inline reference operator()(UInt i, UInt j = 0);
inline const_reference operator()(UInt i, UInt j = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
UInt getSize() const{ return this->size; };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// indice of first element in this circular array
UInt start_position;
/// indice of last element in this circular array
UInt end_position;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "aka_circular_array_inline_impl.cc"
#endif
/// standard output stream operator
template <typename T>
inline std::ostream & operator <<(std::ostream & stream, const CircularArray<T> & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_AKA_CIRCULAR_ARRAY_HH__ */
diff --git a/src/common/aka_circular_array_inline_impl.cc b/src/common/aka_circular_array_inline_impl.cc
index 32abf2b6f..1691e5a8d 100644
--- a/src/common/aka_circular_array_inline_impl.cc
+++ b/src/common/aka_circular_array_inline_impl.cc
@@ -1,83 +1,84 @@
/**
* @file aka_circular_array_inline_impl.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri Nov 11 2011
- * @date last modification: Mon Jun 02 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief implementation of circular array
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* Inline Functions Array<T> */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<class T>
inline typename CircularArray<T>::reference CircularArray<T>::operator()(UInt i, UInt j) {
AKANTU_DEBUG_ASSERT(end_position != start_position,
"The array \"" << this->id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < (end_position - start_position + this->allocated_size) % this->allocated_size + 1)
&& (j < this->nb_component),
"The value at position [" << i << "," << j
<< "] is out of range in array \"" << this->id << "\"");
return this->values[((i+start_position)%this->allocated_size)*this->nb_component + j];
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline typename CircularArray<T>::const_reference CircularArray<T>::operator()(UInt i, UInt j) const {
AKANTU_DEBUG_ASSERT(end_position != start_position,
"The array \"" << this->id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < (end_position - start_position + this->allocated_size) % this->allocated_size + 1)
&& (j < this->nb_component),
"The value at position [" << i << "," << j
<< "] is out of range in array \"" << this->id << "\"");
return this->values[((i+start_position)%this->allocated_size)*this->nb_component + j];
}
/* -------------------------------------------------------------------------- */
template <class T>
inline void CircularArray<T>::makeStep() {
AKANTU_DEBUG_IN();
start_position = (start_position+1) % this->allocated_size;
end_position = (end_position+1) % this->allocated_size;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T>
void CircularArray<T>::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "CircularArray<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
stream << space << " + start_position : " << this->start_position << std::endl;
stream << space << " + end_position : " << this->end_position << std::endl;
Array<T>::printself(stream, indent+1);
stream << space << "]" << std::endl;
}
diff --git a/src/common/aka_common.cc b/src/common/aka_common.cc
index 77ceeb4d4..cc1df0c57 100644
--- a/src/common/aka_common.cc
+++ b/src/common/aka_common.cc
@@ -1,149 +1,151 @@
/**
* @file aka_common.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Wed Jan 13 2016
*
* @brief Initialization of global variables
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_static_memory.hh"
#include "static_communicator.hh"
#include "static_solver.hh"
#include "aka_random_generator.hh"
#include "parser.hh"
#include "cppargparse.hh"
/* -------------------------------------------------------------------------- */
#include <ctime>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
void initialize(int & argc, char **& argv) {
AKANTU_DEBUG_IN();
initialize("", argc, argv);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void initialize(const std::string & input_file, int & argc, char **& argv) {
AKANTU_DEBUG_IN();
StaticMemory::getStaticMemory();
StaticCommunicator & comm =
StaticCommunicator::getStaticCommunicator(argc, argv);
debug::debugger.setParallelContext(comm.whoAmI(), comm.getNbProc());
debug::initSignalHandler();
static_argparser.setParallelContext(comm.whoAmI(), comm.getNbProc());
static_argparser.setExternalExitFunction(debug::exit);
static_argparser.addArgument("--aka_input_file", "Akantu's input file", 1,
cppargparse::_string, std::string());
static_argparser.addArgument(
"--aka_debug_level",
std::string("Akantu's overall debug level") +
std::string(" (0: error, 1: exceptions, 4: warnings, 5: info, ..., "
"100: dump,") +
std::string(" more info on levels can be foind in aka_error.hh)"),
1, cppargparse::_integer, int(dblWarning));
static_argparser.addArgument(
"--aka_print_backtrace",
"Should Akantu print a backtrace in case of error", 0,
cppargparse::_boolean, false, true);
static_argparser.parse(argc, argv, cppargparse::_remove_parsed);
std::string infile = static_argparser["aka_input_file"];
if (infile == "")
infile = input_file;
debug::setDebugLevel(dblError);
if ("" != infile) {
readInputFile(infile);
}
long int seed;
try {
seed = static_parser.getParameter("seed", _ppsc_current_scope);
} catch (debug::Exception &) {
seed = time(NULL);
}
int dbl_level = static_argparser["aka_debug_level"];
debug::setDebugLevel(DebugLevel(dbl_level));
debug::debugger.printBacktrace(static_argparser["aka_print_backtrace"]);
seed *= (comm.whoAmI() + 1);
#if not defined(_WIN32)
Rand48Generator<Real>::seed(seed);
#endif
RandGenerator<Real>::seed(seed);
AKANTU_DEBUG_INFO("Random seed set to " << seed);
/// initialize external solvers
StaticSolver::getStaticSolver().initialize(argc, argv);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void finalize() {
AKANTU_DEBUG_IN();
if (StaticMemory::isInstantiated())
delete &(StaticMemory::getStaticMemory());
if (StaticCommunicator::isInstantiated()) {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
delete &comm;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void readInputFile(const std::string & input_file) {
static_parser.parse(input_file);
}
/* -------------------------------------------------------------------------- */
cppargparse::ArgumentParser & getStaticArgumentParser() {
return static_argparser;
}
/* -------------------------------------------------------------------------- */
Parser & getStaticParser() { return static_parser; }
/* -------------------------------------------------------------------------- */
const ParserSection & getUserParser() {
return *(static_parser.getSubSections(_st_user).first);
}
__END_AKANTU__
diff --git a/src/common/aka_common.hh b/src/common/aka_common.hh
index 1fbd72097..857c0a661 100644
--- a/src/common/aka_common.hh
+++ b/src/common/aka_common.hh
@@ -1,489 +1,490 @@
/**
* @file aka_common.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Wed Jan 13 2016
*
* @brief common type descriptions for akantu
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* All common things to be included in the projects files
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COMMON_HH__
#define __AKANTU_COMMON_HH__
/* -------------------------------------------------------------------------- */
#include <list>
#include <limits>
/* -------------------------------------------------------------------------- */
#define __BEGIN_AKANTU__ namespace akantu {
#define __END_AKANTU__ };
/* -------------------------------------------------------------------------- */
#define __BEGIN_AKANTU_DUMPER__ namespace dumper {
#define __END_AKANTU_DUMPER__ }
/* -------------------------------------------------------------------------- */
#if defined(WIN32)
# define __attribute__(x)
#endif
/* -------------------------------------------------------------------------- */
#include "aka_config.hh"
#include "aka_error.hh"
#include "aka_safe_enum.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Common types */
/* -------------------------------------------------------------------------- */
typedef std::string ID;
static const Real UINT_INIT_VALUE = Real(0.);
#ifdef AKANTU_NDEBUG
static const Real REAL_INIT_VALUE = Real(0.);
#else
static const Real REAL_INIT_VALUE = std::numeric_limits<Real>::quiet_NaN();
#endif
/* -------------------------------------------------------------------------- */
/* Memory types */
/* -------------------------------------------------------------------------- */
typedef UInt MemoryID;
typedef std::string Surface;
typedef std::pair<Surface, Surface> SurfacePair;
typedef std::list< SurfacePair > SurfacePairList;
/* -------------------------------------------------------------------------- */
extern const UInt _all_dimensions;
/* -------------------------------------------------------------------------- */
/* Mesh/FEM/Model types */
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include "aka_element_classes_info.hh"
__BEGIN_AKANTU__
/// small help to use names for directions
enum SpacialDirection {
_x = 0,
_y = 1,
_z = 2
};
/// enum MeshIOType type of mesh reader/writer
enum MeshIOType {
_miot_auto, ///< Auto guess of the reader to use based on the extension
_miot_gmsh, ///< Gmsh files
_miot_gmsh_struct, ///< Gsmh reader with reintpretation of elements has structures elements
_miot_diana, ///< TNO Diana mesh format
_miot_abaqus ///< Abaqus mesh format
};
/// enum AnalysisMethod type of solving method used to solve the equation of motion
enum AnalysisMethod {
_static,
_implicit_dynamic,
_explicit_lumped_mass,
_explicit_lumped_capacity,
_explicit_consistent_mass
};
//! enum ContactResolutionMethod types of solving for the contact
enum ContactResolutionMethod {
_penalty,
_lagrangian,
_augmented_lagrangian,
_nitsche,
_mortar
};
//! enum ContactImplementationMethod types for different contact implementations
enum ContactImplementationMethod {
_none,
_uzawa,
_generalized_newton
};
/// enum SolveConvergenceMethod different resolution algorithms
enum SolveConvergenceMethod {
_scm_newton_raphson_tangent, ///< Newton-Raphson with tangent matrix
_scm_newton_raphson_tangent_modified, ///< Newton-Raphson with constant tangent matrix
_scm_newton_raphson_tangent_not_computed ///< Newton-Raphson with constant tangent matrix (user has to assemble it)
};
/// enum SolveConvergenceCriteria different convergence criteria
enum SolveConvergenceCriteria {
_scc_residual, ///< Use residual to test the convergence
_scc_increment, ///< Use increment to test the convergence
_scc_residual_mass_wgh ///< Use residual weighted by inv. nodal mass to testb
};
/// enum CohesiveMethod type of insertion of cohesive elements
enum CohesiveMethod {
_intrinsic,
_extrinsic
};
/// myfunction(double * position, double * stress/force, double * normal, unsigned int material_id)
typedef void (*BoundaryFunction)(double *,double *, double*, unsigned int);
/// @enum BoundaryFunctionType type of function passed for boundary conditions
enum BoundaryFunctionType {
_bft_stress,
_bft_traction,
_bft_traction_local
};
/// @enum SparseMatrixType type of sparse matrix used
enum SparseMatrixType {
_unsymmetric,
_symmetric
};
/* -------------------------------------------------------------------------- */
/* Contact */
/* -------------------------------------------------------------------------- */
typedef ID ContactID;
typedef ID ContactSearchID;
typedef ID ContactNeighborStructureID;
enum ContactType {
_ct_not_defined = 0,
_ct_2d_expli = 1,
_ct_3d_expli = 2,
_ct_rigid = 3
};
enum ContactSearchType {
_cst_not_defined = 0,
_cst_2d_expli = 1,
_cst_expli = 2
};
enum ContactNeighborStructureType {
_cnst_not_defined = 0,
_cnst_regular_grid = 1,
_cnst_2d_grid = 2
};
/* -------------------------------------------------------------------------- */
/* Friction */
/* -------------------------------------------------------------------------- */
typedef ID FrictionID;
/* -------------------------------------------------------------------------- */
/* Ghosts handling */
/* -------------------------------------------------------------------------- */
typedef ID SynchronizerID;
/// @enum CommunicatorType type of communication method to use
enum CommunicatorType {
_communicator_mpi,
_communicator_dummy
};
/// @enum SynchronizationTag type of synchronizations
enum SynchronizationTag {
//--- SolidMechanicsModel tags ---
_gst_smm_mass, //< synchronization of the SolidMechanicsModel.mass
_gst_smm_for_gradu, //< synchronization of the SolidMechanicsModel.displacement
_gst_smm_boundary, //< synchronization of the boundary, forces, velocities and displacement
_gst_smm_uv, //< synchronization of the nodal velocities and displacement
_gst_smm_res, //< synchronization of the nodal residual
_gst_smm_init_mat, //< synchronization of the data to initialize materials
_gst_smm_stress, //< synchronization of the stresses to compute the internal forces
_gst_smmc_facets, //< synchronization of facet data to setup facet synch
_gst_smmc_facets_conn, //< synchronization of facet global connectivity
_gst_smmc_facets_stress, //< synchronization of facets' stress to setup facet synch
_gst_smmc_damage, //< synchronization of damage
//--- GlobalIdsUpdater tags ---
_gst_giu_global_conn, //< synchronization of global connectivities
//--- CohesiveElementInserter tags ---
_gst_ce_groups, //< synchronization of cohesive element insertion depending on facet groups
//--- GroupManager tags ---
_gst_gm_clusters, //< synchronization of clusters
//--- HeatTransfer tags ---
_gst_htm_capacity, //< synchronization of the nodal heat capacity
_gst_htm_temperature, //< synchronization of the nodal temperature
_gst_htm_gradient_temperature, //< synchronization of the element gradient temperature
//--- LevelSet tags ---
/// synchronization of the nodal level set value phi
_gst_htm_phi,
/// synchronization of the element gradient phi
_gst_htm_gradient_phi,
//--- Material non local ---
_gst_mnl_for_average, //< synchronization of data to average in non local material
_gst_mnl_weight, //< synchronization of data for the weight computations
//--- NeighborhoodSynchronization tags ---
_gst_nh_criterion,
//--- General tags ---
_gst_test, //< Test tag
_gst_user_1, //< tag for user simulations
_gst_user_2, //< tag for user simulations
_gst_material_id, //< synchronization of the material ids
_gst_for_dump, //< everything that needs to be synch before dump
//--- Contact & Friction ---
_gst_cf_nodal, //< synchronization of disp, velo, and current position
_gst_cf_incr, //< synchronization of increment
///--- Solver tags ---
_gst_solver_solution //< synchronization of the solution obained with the PETSc solver
};
/// standard output stream operator for SynchronizationTag
inline std::ostream & operator <<(std::ostream & stream, SynchronizationTag type);
/// @enum GhostType type of ghost
enum GhostType {
_not_ghost,
_ghost,
_casper // not used but a real cute ghost
};
/* -------------------------------------------------------------------------- */
struct GhostType_def {
typedef GhostType type;
static const type _begin_ = _not_ghost;
static const type _end_ = _casper;
};
typedef safe_enum<GhostType_def> ghost_type_t;
/// standard output stream operator for GhostType
inline std::ostream & operator <<(std::ostream & stream, GhostType type);
/// @enum SynchronizerOperation reduce operation that the synchronizer can perform
enum SynchronizerOperation {
_so_sum,
_so_min,
_so_max,
_so_prod,
_so_land,
_so_band,
_so_lor,
_so_bor,
_so_lxor,
_so_bxor,
_so_min_loc,
_so_max_loc,
_so_null
};
/* -------------------------------------------------------------------------- */
/* Global defines */
/* -------------------------------------------------------------------------- */
#define AKANTU_MIN_ALLOCATION 2000
#define AKANTU_INDENT " "
#define AKANTU_INCLUDE_INLINE_IMPL
/* -------------------------------------------------------------------------- */
// int 2 type construct
template <int d>
struct Int2Type {
enum { result = d };
};
// type 2 type construct
template <class T>
class Type2Type {
typedef T OriginalType;
};
/* -------------------------------------------------------------------------- */
template<class T>
struct is_scalar {
enum{ value = false };
};
#define AKANTU_SPECIFY_IS_SCALAR(type) \
template<> \
struct is_scalar<type> { \
enum { value = true }; \
}
AKANTU_SPECIFY_IS_SCALAR(Real);
AKANTU_SPECIFY_IS_SCALAR(UInt);
AKANTU_SPECIFY_IS_SCALAR(Int);
AKANTU_SPECIFY_IS_SCALAR(bool);
template < typename T1, typename T2 >
struct is_same {
enum { value = false }; // is_same represents a bool.
};
template < typename T >
struct is_same<T, T> {
enum { value = true };
};
/* -------------------------------------------------------------------------- */
#define AKANTU_SET_MACRO(name, variable, type) \
inline void set##name (type variable) { \
this->variable = variable; \
}
#define AKANTU_GET_MACRO(name, variable, type) \
inline type get##name () const { \
return variable; \
}
#define AKANTU_GET_MACRO_NOT_CONST(name, variable, type) \
inline type get##name () { \
return variable; \
}
#define AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, \
support, con) \
inline con Array<type> & \
get##name (const support & el_type, \
const GhostType & ghost_type = _not_ghost) con { \
return variable(el_type, ghost_type); \
}
#define AKANTU_GET_MACRO_BY_ELEMENT_TYPE(name, variable, type) \
AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType,)
#define AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(name, variable, type) \
AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType, const)
#define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE(name, variable, type) \
AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType,)
#define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE_CONST(name, variable, type) \
AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType, const)
/* -------------------------------------------------------------------------- */
/// initialize the static part of akantu
void initialize(int & argc, char ** & argv);
/// initialize the static part of akantu and read the global input_file
void initialize(const std::string & input_file, int & argc, char ** & argv);
/* -------------------------------------------------------------------------- */
/// finilize correctly akantu and clean the memory
void finalize ();
/* -------------------------------------------------------------------------- */
/// Read an new input file
void readInputFile(const std::string & input_file);
/* -------------------------------------------------------------------------- */
/*
* For intel compiler annoying remark
*/
#if defined(__INTEL_COMPILER)
/// remark #981: operands are evaluated in unspecified order
#pragma warning ( disable : 981 )
/// remark #383: value copied to temporary, reference to temporary used
#pragma warning ( disable : 383 )
#endif //defined(__INTEL_COMPILER)
/* -------------------------------------------------------------------------- */
/* string manipulation */
/* -------------------------------------------------------------------------- */
inline std::string to_lower(const std::string & str);
/* -------------------------------------------------------------------------- */
inline std::string trim(const std::string & to_trim);
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/// give a string representation of the a human readable size in bit
template<typename T>
std::string printMemorySize(UInt size);
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include "aka_fwd.hh"
__BEGIN_AKANTU__
/// get access to the internal argument parser
cppargparse::ArgumentParser & getStaticArgumentParser();
/// get access to the internal input file parser
Parser & getStaticParser();
/// get access to the user part of the internal input file parser
const ParserSection & getUserParser();
__END_AKANTU__
#include "aka_common_inline_impl.cc"
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_UNORDERED_MAP_IS_CXX11)
__BEGIN_AKANTU_UNORDERED_MAP__
#if AKANTU_INTEGER_SIZE == 4
#define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b9
#elif AKANTU_INTEGER_SIZE == 8
#define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b97f4a7c13LL
#endif
/**
* Hashing function for pairs based on hash_combine from boost The magic number
* is coming from the golden number @f[\phi = \frac{1 + \sqrt5}{2}@f]
* @f[\frac{2^32}{\phi} = 0x9e3779b9@f]
* http://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine
* http://burtleburtle.net/bob/hash/doobs.html
*/
template <typename a, typename b> struct hash< std::pair<a, b> > {
public:
hash() : ah(), bh() {}
size_t operator()(const std::pair<a, b> & p) const {
size_t seed = ah(p.first);
return bh(p.second) + AKANTU_HASH_COMBINE_MAGIC_NUMBER + (seed << 6) +
(seed >> 2);
}
private:
const hash<a> ah;
const hash<b> bh;
};
__END_AKANTU_UNORDERED_MAP__
#endif
#endif /* __AKANTU_COMMON_HH__ */
diff --git a/src/common/aka_common_inline_impl.cc b/src/common/aka_common_inline_impl.cc
index 159d45f87..2005db246 100644
--- a/src/common/aka_common_inline_impl.cc
+++ b/src/common/aka_common_inline_impl.cc
@@ -1,179 +1,180 @@
/**
* @file aka_common_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Dec 01 2011
- * @date last modification: Wed Jul 23 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief inline implementations of common akantu type descriptions
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* All common things to be included in the projects files
*
*/
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <cctype>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/// standard output stream operator for GhostType
inline std::ostream & operator <<(std::ostream & stream, GhostType type)
{
switch(type)
{
case _not_ghost : stream << "not_ghost"; break;
case _ghost : stream << "ghost" ; break;
case _casper : stream << "Casper the friendly ghost"; break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator for SynchronizationTag
inline std::ostream & operator <<(std::ostream & stream, SynchronizationTag type)
{
switch(type)
{
case _gst_smm_mass : stream << "_gst_smm_mass" ; break;
case _gst_smm_for_gradu : stream << "_gst_smm_for_gradu" ; break;
case _gst_smm_boundary : stream << "_gst_smm_boundary" ; break;
case _gst_smm_uv : stream << "_gst_smm_uv" ; break;
case _gst_smm_res : stream << "_gst_smm_res" ; break;
case _gst_smm_init_mat : stream << "_gst_smm_init_mat" ; break;
case _gst_smm_stress : stream << "_gst_smm_stress" ; break;
case _gst_smmc_facets : stream << "_gst_smmc_facets" ; break;
case _gst_smmc_facets_conn : stream << "_gst_smmc_facets_conn" ; break;
case _gst_smmc_facets_stress : stream << "_gst_smmc_facets_stress" ; break;
case _gst_smmc_damage : stream << "_gst_smmc_damage" ; break;
case _gst_giu_global_conn : stream << "_gst_giu_global_conn" ; break;
case _gst_ce_groups : stream << "_gst_ce_groups" ; break;
case _gst_gm_clusters : stream << "_gst_gm_clusters" ; break;
case _gst_htm_capacity : stream << "_gst_htm_capacity" ; break;
case _gst_htm_temperature : stream << "_gst_htm_temperature" ; break;
case _gst_htm_gradient_temperature : stream << "_gst_htm_gradient_temperature"; break;
case _gst_htm_phi : stream << "_gst_htm_phi" ; break;
case _gst_htm_gradient_phi : stream << "_gst_htm_gradient_phi" ; break;
case _gst_mnl_for_average : stream << "_gst_mnl_for_average" ; break;
case _gst_mnl_weight : stream << "_gst_mnl_weight" ; break;
case _gst_nh_criterion : stream << "_gst_nh_criterion" ; break;
case _gst_test : stream << "_gst_test" ; break;
case _gst_user_1 : stream << "_gst_user_1" ; break;
case _gst_user_2 : stream << "_gst_user_2" ; break;
case _gst_material_id : stream << "_gst_material_id" ; break;
case _gst_for_dump : stream << "_gst_for_dump" ; break;
case _gst_cf_nodal : stream << "_gst_cf_nodal" ; break;
case _gst_cf_incr : stream << "_gst_cf_incr" ; break;
case _gst_solver_solution : stream << "_gst_solver_solution" ; break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator for SolveConvergenceCriteria
inline std::ostream & operator <<(std::ostream & stream, SolveConvergenceCriteria criteria)
{
switch(criteria) {
case _scc_residual : stream << "_scc_residual" ; break;
case _scc_increment: stream << "_scc_increment"; break;
case _scc_residual_mass_wgh: stream << "_scc_residual_mass_wgh"; break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
inline std::string to_lower(const std::string & str) {
std::string lstr = str;
std::transform(lstr.begin(),
lstr.end(),
lstr.begin(),
(int(*)(int))tolower);
return lstr;
}
/* -------------------------------------------------------------------------- */
inline std::string trim(const std::string & to_trim) {
std::string trimed = to_trim;
//left trim
trimed.erase(trimed.begin(),
std::find_if(trimed.begin(),
trimed.end(),
std::not1(std::ptr_fun<int, int>(isspace))));
// right trim
trimed.erase(std::find_if(trimed.rbegin(),
trimed.rend(),
std::not1(std::ptr_fun<int, int>(isspace))).base(),
trimed.end());
return trimed;
}
__END_AKANTU__
#include <cmath>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<typename T>
std::string printMemorySize(UInt size) {
Real real_size = size * sizeof(T);
UInt mult = (std::log(real_size) / std::log(2)) / 10;
std::stringstream sstr;
real_size /= Real(1 << (10 * mult));
sstr << std::setprecision(2) << std::fixed << real_size;
std::string size_prefix;
switch(mult) {
case 0: sstr << ""; break;
case 1: sstr << "Ki"; break;
case 2: sstr << "Mi"; break;
case 3: sstr << "Gi"; break; // I started on this type of machines
// (32bit computers) (Nicolas)
case 4: sstr << "Ti"; break;
case 5: sstr << "Pi"; break;
case 6: sstr << "Ei"; break; // theoritical limit of RAM of the current
// computers in 2014 (64bit computers) (Nicolas)
case 7: sstr << "Zi"; break;
case 8: sstr << "Yi"; break;
default:
AKANTU_DEBUG_ERROR("The programmer in 2014 didn't thought so far (even wikipedia does not go further)."
<< " You have at least 1024 times more than a yobibit of RAM!!!"
<< " Just add the prefix corresponding in this switch case.");
}
sstr << "Byte";
return sstr.str();
}
__END_AKANTU__
diff --git a/src/common/aka_config.hh.in b/src/common/aka_config.hh.in
index 94ea058bb..ca7eca4ab 100644
--- a/src/common/aka_config.hh.in
+++ b/src/common/aka_config.hh.in
@@ -1,125 +1,127 @@
/**
* @file aka_config.hh.in
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date Fri Jan 13 12:34:54 2012
+ * @date creation: Sun Sep 26 2010
+ * @date last modification: Fri Dec 11 2015
*
* @brief Compilation time configuration of Akantu
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_CONFIG_HH__
#define __AKANTU_AKA_CONFIG_HH__
#define AKANTU_VERSION_MAJOR @AKANTU_MAJOR_VERSION@
#define AKANTU_VERSION_MINOR @AKANTU_MINOR_VERSION@
#define AKANTU_VERSION_PATCH @AKANTU_PATCH_VERSION@
#define AKANTU_VERSION (AKANTU_VERSION_MAJOR * 100000 \
+ AKANTU_VERSION_MINOR * 1000 \
+ AKANTU_VERSION_PATCH)
@AKANTU_TYPES_EXTRA_INCLUDES@
namespace akantu {
typedef @AKANTU_FLOAT_TYPE@ Real;
typedef @AKANTU_SIGNED_INTEGER_TYPE@ Int;
typedef @AKANTU_UNSIGNED_INTEGER_TYPE@ UInt;
template<class Key, class Ty>
struct unordered_map {
typedef typename @AKANTU_UNORDERED_MAP_TYPE@<Key, Ty> type;
};
template<class T>
std::size_t hash(const T & t) {
typedef typename @AKANTU_HASH_TYPE@<T> hash_type;
return hash_type()(t);
};
}
#define AKANTU_INTEGER_SIZE @AKANTU_INTEGER_SIZE@
#define AKANTU_FLOAT_SIZE @AKANTU_FLOAT_SIZE@
#cmakedefine AKANTU_UNORDERED_MAP_IS_CXX11
#define __BEGIN_AKANTU_UNORDERED_MAP__ \
@AKANTU_UNORDERED_MAP_NAMESPACE_BEGIN@
#define __END_AKANTU_UNORDERED_MAP__ \
@AKANTU_UNORDERED_MAP_NAMESPACE_END@
#cmakedefine AKANTU_HAS_STRDUP
#cmakedefine AKANTU_USE_BLAS
#cmakedefine AKANTU_USE_LAPACK
#cmakedefine AKANTU_PARALLEL
#cmakedefine AKANTU_USE_MPI
#cmakedefine AKANTU_USE_SCOTCH
#cmakedefine AKANTU_USE_PTSCOTCH
#cmakedefine AKANTU_SCOTCH_NO_EXTERN
#cmakedefine AKANTU_USE_MUMPS
#cmakedefine AKANTU_USE_PETSC
#cmakedefine AKANTU_USE_IOHELPER
#cmakedefine AKANTU_USE_QVIEW
#cmakedefine AKANTU_USE_BLACKDYNAMITE
#cmakedefine AKANTU_USE_NLOPT
#cmakedefine AKANTU_USE_CPPARRAY
#cmakedefine AKANTU_USE_OBSOLETE_GETTIMEOFDAY
#cmakedefine AKANTU_EXTRA_MATERIALS
#cmakedefine AKANTU_STUDENTS_EXTRA_PACKAGE
#cmakedefine AKANTU_DAMAGE_NON_LOCAL
#cmakedefine AKANTU_STRUCTURAL_MECHANICS
#cmakedefine AKANTU_HEAT_TRANSFER
#cmakedefine AKANTU_PYTHON_INTERFACE
#cmakedefine AKANTU_COHESIVE_ELEMENT
#cmakedefine AKANTU_PARALLEL_COHESIVE_ELEMENT
#cmakedefine AKANTU_IGFEM
#cmakedefine AKANTU_USE_CGAL
#cmakedefine AKANTU_EMBEDDED
// BOOST Section
#cmakedefine AKANTU_BOOST_CHRONO
#cmakedefine AKANTU_BOOST_SYSTEM
// Experimental part
#cmakedefine AKANTU_CORE_CXX11
// Debug tools
//#cmakedefine AKANTU_NDEBUG
#cmakedefine AKANTU_DEBUG_TOOLS
#cmakedefine READLINK_COMMAND @READLINK_COMMAND@
#cmakedefine ADDR2LINE_COMMAND @ADDR2LINE_COMMAND@
#define __aka_inline__ inline
#endif /* __AKANTU_AKA_CONFIG_HH__ */
diff --git a/src/common/aka_csr.hh b/src/common/aka_csr.hh
index c444d28e4..996032e61 100644
--- a/src/common/aka_csr.hh
+++ b/src/common/aka_csr.hh
@@ -1,228 +1,229 @@
/**
* @file aka_csr.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Apr 20 2011
- * @date last modification: Mon Jun 02 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief A compresed sparse row structure based on akantu Arrays
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_CSR_HH__
#define __AKANTU_AKA_CSR_HH__
__BEGIN_AKANTU__
/**
* This class can be used to store the structure of a sparse matrix or for
* vectors with variable number of component per element
*
* @param nb_rows number of rows of a matrix or size of a vector.
*/
template <typename T>
class CSR {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
CSR(UInt nb_rows = 0) : nb_rows(nb_rows),
rows_offsets(nb_rows + 1, 1, "rows_offsets"),
rows(0, 1, "rows") {
rows_offsets.clear();
};
virtual ~CSR() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// does nothing
inline void beginInsertions() {};
/// insert a new entry val in row row
inline UInt insertInRow(UInt row, const T & val) {
UInt pos = rows_offsets(row)++;
rows(pos) = val;
return pos;
}
/// access an element of the matrix
inline const T & operator()(UInt row, UInt col) const {
AKANTU_DEBUG_ASSERT(rows_offsets(row + 1) - rows_offsets(row) > col, "This element is not present in this CSR");
return rows(rows_offsets(row) + col);
}
/// access an element of the matrix
inline T & operator()(UInt row, UInt col) {
AKANTU_DEBUG_ASSERT(rows_offsets(row + 1) - rows_offsets(row) > col, "This element is not present in this CSR");
return rows(rows_offsets(row) + col);
}
inline void endInsertions() {
for (UInt i = nb_rows; i > 0; --i) rows_offsets(i) = rows_offsets(i-1);
rows_offsets(0) = 0;
}
inline void countToCSR() {
for (UInt i = 1; i < nb_rows; ++i) rows_offsets(i) += rows_offsets(i-1);
for (UInt i = nb_rows; i >= 1; --i) rows_offsets(i) = rows_offsets(i-1);
rows_offsets(0) = 0;
}
inline void clearRows() { rows_offsets.clear(); rows.resize(0); };
inline void resizeRows(UInt nb_rows) {
this->nb_rows = nb_rows;
rows_offsets.resize(nb_rows + 1);
}
inline void resizeCols() {
rows.resize(rows_offsets(nb_rows));
}
inline void copy(Array<UInt> & offsets, Array<T> & values) {
offsets.copy(rows_offsets);
values.copy(rows);
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// returns the number of rows
inline UInt getNbRows() const { return rows_offsets.getSize() - 1; };
/// returns the number of non-empty columns in a given row
inline UInt getNbCols(UInt row) const { return rows_offsets(row + 1) - rows_offsets(row); };
/// returns the offset (start of columns) for a given row
inline UInt & rowOffset(UInt row) { return rows_offsets(row); };
/// iterator on a row
template <class R>
class iterator_internal : public std::iterator<std::bidirectional_iterator_tag, R> {
public:
typedef std::iterator<std::bidirectional_iterator_tag, R> _parent;
typedef typename _parent::pointer pointer;
typedef typename _parent::reference reference;
iterator_internal(pointer x = NULL) : pos(x) {};
iterator_internal(const iterator_internal & it) : pos(it.pos) {};
iterator_internal& operator++() { ++pos; return *this; };
iterator_internal operator++(int) { iterator tmp(*this); operator++(); return tmp; };
iterator_internal& operator--() { --pos; return *this; };
iterator_internal operator--(int) { iterator_internal tmp(*this); operator--(); return tmp; };
bool operator==(const iterator_internal& rhs) { return pos == rhs.pos; };
bool operator!=(const iterator_internal& rhs) { return pos != rhs.pos; };
reference operator*() { return *pos; };
pointer operator->() const { return pos; };
private:
pointer pos;
};
typedef iterator_internal<T> iterator;
typedef iterator_internal<const T> const_iterator;
inline iterator begin(UInt row) { return iterator(rows.storage() + rows_offsets(row)); };
inline iterator end(UInt row) { return iterator(rows.storage() + rows_offsets(row+1)); };
inline const_iterator begin(UInt row) const { return const_iterator(rows.storage() + rows_offsets(row)); };
inline const_iterator end(UInt row) const { return const_iterator(rows.storage() + rows_offsets(row+1)); };
inline iterator rbegin(UInt row) { return iterator(rows.storage() + rows_offsets(row+1) - 1); };
inline iterator rend(UInt row) { return iterator(rows.storage() + rows_offsets(row) - 1); };
inline const Array<UInt> & getRowsOffset() const { return rows_offsets; };
inline const Array<T> & getRows() const { return rows; };
inline Array<T> & getRows() { return rows; };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
UInt nb_rows;
/// array of size nb_rows containing the offset where the values are stored in
Array<UInt> rows_offsets;
/// compressed row values, values of row[i] are stored between rows_offsets[i]
/// and rows_offsets[i+1]
Array<T> rows;
};
/* -------------------------------------------------------------------------- */
/* Data CSR */
/* -------------------------------------------------------------------------- */
/**
* Inherits from CSR<UInt> and can contain information such as matrix values
* where the mother class would be a CSR structure for row and cols
*
* @return nb_rows
*/
template<class T>
class DataCSR : public CSR<UInt> {
public:
DataCSR(UInt nb_rows = 0) : CSR<UInt>(nb_rows), data(0,1) { };
inline void resizeCols() {
CSR<UInt>::resizeCols();
data.resize(rows_offsets(nb_rows));
}
inline const Array<T> & getData() const { return data; };
private:
Array<T> data;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "aka_csr_inline_impl.cc"
/// standard output stream operator
// inline std::ostream & operator <<(std::ostream & stream, const CSR & _this)
// {
// _this.printself(stream);
// return stream;
// }
__END_AKANTU__
#endif /* __AKANTU_AKA_CSR_HH__ */
diff --git a/src/common/aka_element_classes_info.hh.in b/src/common/aka_element_classes_info.hh.in
index 5670dff70..91b46a765 100644
--- a/src/common/aka_element_classes_info.hh.in
+++ b/src/common/aka_element_classes_info.hh.in
@@ -1,195 +1,199 @@
/**
- * @file aka_element_classes_info.hh
+ * @file aka_element_classes_info.hh.in
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Tue May 19 11:43:07 2015
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Sun Jul 19 2015
+ * @date last modification: Fri Oct 16 2015
*
* @brief Declaration of the enums for the element classes
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <boost/preprocessor.hpp>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Element Types */
/* -------------------------------------------------------------------------- */
/// @enum ElementType type of elements
enum ElementType {
_not_defined,
@AKANTU_ELEMENT_TYPES_ENUM@
_max_element_type
};
@AKANTU_ELEMENT_TYPES_BOOST_SEQ@
@AKANTU_ALL_ELEMENT_BOOST_SEQ@
/* -------------------------------------------------------------------------- */
/* Element Kinds */
/* -------------------------------------------------------------------------- */
@AKANTU_ELEMENT_KINDS_BOOST_SEQ@
@AKANTU_ELEMENT_KIND_BOOST_SEQ@
#ifndef SWIG
enum ElementKind {
BOOST_PP_SEQ_ENUM(AKANTU_ELEMENT_KIND),
_ek_not_defined
};
/* -------------------------------------------------------------------------- */
struct ElementKind_def {
typedef ElementKind type;
static const type _begin_ = BOOST_PP_SEQ_HEAD(AKANTU_ELEMENT_KIND);
static const type _end_ = _ek_not_defined;
};
typedef safe_enum<ElementKind_def> element_kind_t;
#else
enum ElementKind;
#endif
/* -------------------------------------------------------------------------- */
/// @enum GeometricalType type of element potentially contained in a Mesh
enum GeometricalType {
@AKANTU_GEOMETRICAL_TYPES_ENUM@
_gt_not_defined
};
/* -------------------------------------------------------------------------- */
/* Interpolation Types */
/* -------------------------------------------------------------------------- */
@AKANTU_INTERPOLATION_TYPES_BOOST_SEQ@
#ifndef SWIG
/// @enum InterpolationType type of elements
enum InterpolationType {
BOOST_PP_SEQ_ENUM(AKANTU_INTERPOLATION_TYPES),
_itp_not_defined
};
#else
enum InterpolationType;
#endif
/* -------------------------------------------------------------------------- */
/* Some sub types less probable to change */
/* -------------------------------------------------------------------------- */
/// @enum GeometricalShapeType types of shapes to define the contains
/// function in the element classes
enum GeometricalShapeType {
_gst_not_defined,
@AKANTU_GEOMETRICAL_SHAPES_ENUM@
};
/* -------------------------------------------------------------------------- */
/// @enum GaussIntergrationType classes of types using common
/// description of the gauss point position and weights
enum GaussIntergrationType {
_git_not_defined,
@AKANTU_GAUSS_INTEGRATION_TYPES_ENUM@
};
/* -------------------------------------------------------------------------- */
/// @enum InterpolationKind the family of interpolation types
enum InterpolationKind {
_itk_not_defined,
@AKANTU_INTERPOLATION_KIND_ENUM@
};
/* -------------------------------------------------------------------------- */
// BOOST PART: TOUCH ONLY IF YOU KNOW WHAT YOU ARE DOING
#define AKANTU_BOOST_CASE_MACRO(r,macro,_type) \
case _type : { macro(_type); break; }
#define AKANTU_BOOST_LIST_SWITCH(macro1, list1, var) \
do { \
switch(var) { \
BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, list1) \
default: { \
AKANTU_DEBUG_ERROR("Type (" << var << ") not handled by this function"); \
} \
} \
} while(0)
#define AKANTU_BOOST_ELEMENT_SWITCH(macro1, list1) \
AKANTU_BOOST_LIST_SWITCH(macro1, list1, type)
#define AKANTU_BOOST_ALL_ELEMENT_SWITCH(macro) \
AKANTU_BOOST_ELEMENT_SWITCH(macro, \
AKANTU_ALL_ELEMENT_TYPE)
#define AKANTU_BOOST_LIST_MACRO(r, macro, type) \
macro(type)
#define AKANTU_BOOST_APPLY_ON_LIST(macro, list) \
BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_LIST_MACRO, macro, list)
#define AKANTU_BOOST_ALL_ELEMENT_LIST(macro) \
AKANTU_BOOST_APPLY_ON_LIST(macro, \
AKANTU_ALL_ELEMENT_TYPE)
#define AKANTU_GET_ELEMENT_LIST(kind) \
AKANTU##kind##_ELEMENT_TYPE
#define AKANTU_BOOST_KIND_ELEMENT_SWITCH(macro, kind) \
AKANTU_BOOST_ELEMENT_SWITCH(macro, \
AKANTU_GET_ELEMENT_LIST(kind))
// BOOST_PP_SEQ_TO_LIST does not exists in Boost < 1.49
#define AKANTU_GENERATE_KIND_LIST(seq) \
BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(seq), \
BOOST_PP_SEQ_TO_TUPLE(seq))
#define AKANTU_ELEMENT_KIND_BOOST_LIST AKANTU_GENERATE_KIND_LIST(AKANTU_ELEMENT_KIND)
#define AKANTU_BOOST_ALL_KIND_LIST(macro, list) \
BOOST_PP_LIST_FOR_EACH(AKANTU_BOOST_LIST_MACRO, macro, list)
#define AKANTU_BOOST_ALL_KIND(macro) \
AKANTU_BOOST_ALL_KIND_LIST(macro, AKANTU_ELEMENT_KIND_BOOST_LIST)
#define AKANTU_BOOST_ALL_KIND_SWITCH(macro) \
AKANTU_BOOST_LIST_SWITCH(macro, \
AKANTU_ELEMENT_KIND, \
kind)
@AKANTU_ELEMENT_KINDS_BOOST_MACROS@
// /// define kept for compatibility reasons (they are most probably not needed
// /// anymore) \todo check if they can be removed
// #define AKANTU_REGULAR_ELEMENT_TYPE AKANTU_ek_regular_ELEMENT_TYPE
// #define AKANTU_COHESIVE_ELEMENT_TYPE AKANTU_ek_cohesive_ELEMENT_TYPE
// #define AKANTU_STRUCTURAL_ELEMENT_TYPE AKANTU_ek_structural_ELEMENT_TYPE
// #define AKANTU_IGFEM_ELEMENT_TYPE AKANTU_ek_igfem_ELEMENT_TYPE
/* -------------------------------------------------------------------------- */
/* Lists of interests for FEEngineTemplate functions */
/* -------------------------------------------------------------------------- */
@AKANTU_FE_ENGINE_LISTS@
__END_AKANTU__
#include "aka_element_classes_info_inline_impl.cc"
diff --git a/src/common/aka_element_classes_info_inline_impl.cc b/src/common/aka_element_classes_info_inline_impl.cc
index b160d5e3c..e9d7877ec 100644
--- a/src/common/aka_element_classes_info_inline_impl.cc
+++ b/src/common/aka_element_classes_info_inline_impl.cc
@@ -1,92 +1,96 @@
/**
* @file aka_element_classes_info_inline_impl.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Tue May 19 11:48:58 2015
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Thu Jun 18 2015
+ * @date last modification: Sun Jul 19 2015
*
* @brief Implementation of the streaming fonction for the element classes enums
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
#define STRINGIFY(type) \
stream << BOOST_PP_STRINGIZE(type)
/* -------------------------------------------------------------------------- */
//! standard output stream operator for ElementType
inline std::ostream & operator <<(std::ostream & stream, ElementType type) {
switch(type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, \
STRINGIFY, \
AKANTU_ALL_ELEMENT_TYPE)
case _not_defined: stream << "_not_defined"; break;
case _max_element_type: stream << "_max_element_type"; break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
//! standard input stream operator for ElementType
inline std::istream & operator >>(std::istream & stream, ElementType & type) {
#define IF_SEQUENCE(_type) \
else if (tmp == BOOST_PP_STRINGIZE(_type)) type = _type;
std::string tmp;
stream >> tmp;
if (1 == 2) {}
BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_LIST_MACRO, \
IF_SEQUENCE, \
AKANTU_ALL_ELEMENT_TYPE)
else AKANTU_EXCEPTION("unknown element type: '" << tmp << "'");
#undef IF_SEQUENCE
return stream;
}
/* -------------------------------------------------------------------------- */
//! standard output stream operator for ElementType
inline std::ostream & operator <<(std::ostream & stream, ElementKind kind ) {
AKANTU_BOOST_ALL_KIND_SWITCH(STRINGIFY);
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator for InterpolationType
inline std::ostream & operator <<(std::ostream & stream, InterpolationType type)
{
switch(type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, \
STRINGIFY, \
AKANTU_INTERPOLATION_TYPES)
case _itp_not_defined : stream << "_itp_not_defined" ; break;
}
return stream;
}
#undef STRINGIFY
__END_AKANTU__
diff --git a/src/common/aka_error.cc b/src/common/aka_error.cc
index a595a4cf4..b35c54446 100644
--- a/src/common/aka_error.cc
+++ b/src/common/aka_error.cc
@@ -1,354 +1,355 @@
/**
* @file aka_error.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Sep 06 2010
- * @date last modification: Tue Jul 29 2014
+ * @date last modification: Mon Nov 16 2015
*
* @brief handling of errors
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_config.hh"
#include "aka_error.hh"
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <csignal>
#if (defined(READLINK_COMMAND) || \
defined(ADDR2LINE_COMMAND)) && \
(not defined(_WIN32))
# include <execinfo.h>
# include <sys/wait.h>
#endif
#include <cxxabi.h>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <cstring>
#include <map>
#include <sys/types.h>
#include <unistd.h>
#if defined(AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
# include <sys/time.h>
#else
# include <time.h>
#endif
#ifdef AKANTU_USE_MPI
# include <mpi.h>
#endif
#define __BEGIN_AKANTU_DEBUG__ namespace akantu { namespace debug {
#define __END_AKANTU_DEBUG__ } }
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU_DEBUG__
static void printBacktraceAndExit(int sig) {
printBacktrace(sig);
debugger.exit(-50);
}
/* ------------------------------------------------------------------------ */
void initSignalHandler() {
#if not defined(_WIN32)
struct sigaction action;
action.sa_handler = &printBacktraceAndExit;
sigemptyset(&(action.sa_mask));
action.sa_flags = SA_RESETHAND;
sigaction(SIGSEGV, &action, NULL);
sigaction(SIGABRT, &action, NULL);
#else
std::signal(SIGSEGV, &printBacktraceAndExit);
std::signal(SIGABRT, &printBacktraceAndExit);
#endif
}
/* ------------------------------------------------------------------------ */
std::string demangle(const char *symbol) {
int status;
std::string result;
char *demangled_name;
if ((demangled_name = abi::__cxa_demangle(symbol, NULL, 0, &status)) != NULL) {
result = demangled_name;
free(demangled_name);
} else {
result = symbol;
}
return result;
}
/* ------------------------------------------------------------------------ */
#if (defined(READLINK_COMMAND) || defined(ADDR2LINK_COMMAND)) && (not defined(_WIN32))
std::string exec(std::string cmd) {
FILE *pipe = popen(cmd.c_str(), "r");
if (!pipe) return "";
char buffer[1024];
std::string result = "";
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
result = result.substr(0, result.size() - 1);
pclose(pipe);
return result;
}
#endif
/* ------------------------------------------------------------------------ */
void printBacktrace(__attribute__((unused)) int sig) {
AKANTU_DEBUG_INFO("Caught signal " << sig << "!");
#if not defined(_WIN32)
#if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
std::string me = "";
char buf[1024];
/* The manpage says it won't null terminate. Let's zero the buffer. */
memset(buf, 0, sizeof(buf));
/* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */
if (readlink("/proc/self/exe", buf, sizeof(buf) - 1))
me = std::string(buf);
std::ifstream inmaps;
inmaps.open("/proc/self/maps");
std::map <std::string, size_t> addr_map;
std::string line;
while (inmaps.good()) {
std::getline(inmaps, line);
std::stringstream sstr(line);
size_t first = line.find('-');
std::stringstream sstra(line.substr(0, first));
size_t addr; sstra >> std::hex >> addr;
std::string lib;
sstr >> lib;
sstr >> lib;
sstr >> lib;
sstr >> lib;
sstr >> lib;
sstr >> lib;
if (lib != "" && addr_map.find(lib) == addr_map.end()) {
addr_map[lib] = addr;
}
}
if (me != "") addr_map[me] = 0;
#endif
/// \todo for windows this part could be coded using CaptureStackBackTrace and SymFromAddr
const size_t max_depth = 100;
size_t stack_depth;
void *stack_addrs[max_depth];
char **stack_strings;
size_t i;
stack_depth = backtrace(stack_addrs, max_depth);
stack_strings = backtrace_symbols(stack_addrs, stack_depth);
std::cerr << "BACKTRACE : " << stack_depth << " stack frames." << std::endl;
size_t w = size_t(std::floor(log(double(stack_depth)) / std::log(10.)) + 1);
/// -1 to remove the call to the printBacktrace function
for (i = 1; i < stack_depth; i++) {
std::cerr << std::dec << " [" << std::setw(w) << i << "] ";
std::string bt_line(stack_strings[i]);
size_t first, second;
if ((first = bt_line.find('(')) != std::string::npos && (second = bt_line.find('+')) != std::string::npos) {
std::string location = bt_line.substr(0, first);
#if defined(READLINK_COMMAND)
location = exec(std::string(BOOST_PP_STRINGIZE(READLINK_COMMAND)) + std::string(" -f ") + location);
#endif
std::string call = demangle(bt_line.substr(first + 1, second - first - 1).c_str());
size_t f = bt_line.find('[');
size_t s = bt_line.find(']');
std::string address = bt_line.substr(f + 1, s - f - 1);
std::stringstream sstra(address);
size_t addr; sstra >> std::hex >> addr;
std::cerr << location << " [" << call << "]";
#if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
std::map <std::string, size_t>::iterator it = addr_map.find(location);
if (it != addr_map.end()) {
std::stringstream syscom;
syscom << BOOST_PP_STRINGIZE(ADDR2LINE_COMMAND) << " 0x" << std::hex << (addr - it->second) << " -i -e " << location;
std::string line = exec(syscom.str());
std::cerr << " (" << line << ")" << std::endl;
} else {
#endif
std::cerr << " (0x" << std::hex << addr << ")" << std::endl;
#if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
}
#endif
} else {
std::cerr << bt_line << std::endl;
}
}
free(stack_strings);
std::cerr << "END BACKTRACE" << std::endl;
#endif
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
Debugger::Debugger() {
cout = &std::cerr;
level = dblWarning;
parallel_context = "";
file_open = false;
print_backtrace = false;
}
/* ------------------------------------------------------------------------ */
Debugger::~Debugger() {
if (file_open) {
dynamic_cast <std::ofstream *>(cout)->close();
delete cout;
}
}
/* ------------------------------------------------------------------------ */
void Debugger::exit(int status) {
if (status != EXIT_SUCCESS && status != -50) {
#ifndef AKANTU_NDEBUG
int * a = NULL;
*a = 1;
#endif
if(this->print_backtrace)
akantu::debug::printBacktrace(15);
}
#ifdef AKANTU_USE_MPI
if (status != EXIT_SUCCESS)
MPI_Abort(MPI_COMM_WORLD, MPI_ERR_UNKNOWN);
#endif
std::exit(status); // not called when compiled with MPI due to MPI_Abort, but
// MPI_Abort does not have the noreturn attribute
}
/*------------------------------------------------------------------------- */
void Debugger::throwException(const std::string & info,
const std::string & file,
unsigned int line,
__attribute__((unused)) bool silent,
__attribute__((unused)) const std::string & location) const
throw(akantu::debug::Exception) {
#if !defined(AKANTU_NDEBUG)
if (!silent) {
printMessage("###", dblWarning, info + location);
}
#endif
debug::Exception ex(info, file, line);
throw ex;
}
/* ------------------------------------------------------------------------ */
void Debugger::printMessage(const std::string & prefix,
const DebugLevel & level,
const std::string & info) const {
if (this->level >= level) {
#if defined(AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
struct timeval time;
gettimeofday(&time, NULL);
double timestamp = time.tv_sec * 1e6 + time.tv_usec; /*in us*/
#else
struct timespec time;
clock_gettime(CLOCK_REALTIME_COARSE, &time);
double timestamp = time.tv_sec * 1e6 + time.tv_nsec * 1e-3; /*in us*/
#endif
*(cout) << parallel_context
<< "{" << (unsigned int)timestamp << "} "
<< prefix << " " << info
<< std::endl;
}
}
/* ------------------------------------------------------------------------ */
void Debugger::setDebugLevel(const DebugLevel & level) {
this->level = level;
}
/* ------------------------------------------------------------------------ */
const DebugLevel & Debugger::getDebugLevel() const {
return level;
}
/* ------------------------------------------------------------------------ */
void Debugger::setLogFile(const std::string & filename) {
if (file_open) {
dynamic_cast <std::ofstream *>(cout)->close();
delete cout;
}
std::ofstream *fileout = new std::ofstream(filename.c_str());
file_open = true;
cout = fileout;
}
std::ostream & Debugger::getOutputStream() {
return *cout;
}
/* ------------------------------------------------------------------------ */
void Debugger::setParallelContext(int rank, int size) {
std::stringstream sstr;
UInt pad = std::ceil(std::log10(size));
sstr << "<" << getpid() << ">[R" << std::setfill(' ') << std::right << std::setw(pad)
<< rank << "|S" << size << "] ";
parallel_context = sstr.str();
}
void setDebugLevel(const DebugLevel & level) {
debugger.setDebugLevel(level);
}
const DebugLevel & getDebugLevel() {
return debugger.getDebugLevel();
}
/* -------------------------------------------------------------------------- */
void exit(int status) {
debugger.exit(status);
}
__END_AKANTU_DEBUG__
diff --git a/src/common/aka_error.hh b/src/common/aka_error.hh
index 2e3992faa..9ba4ddfee 100644
--- a/src/common/aka_error.hh
+++ b/src/common/aka_error.hh
@@ -1,295 +1,296 @@
/**
* @file aka_error.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
- * @date last modification: Tue Jul 08 2014
+ * @date last modification: Mon Jul 13 2015
*
* @brief error management and internal exceptions
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ERROR_HH__
#define __AKANTU_ERROR_HH__
/* -------------------------------------------------------------------------- */
#include <ostream>
#include <sstream>
#include <cstdlib>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
enum DebugLevel {
dbl0 = 0,
dblError = 0,
dblAssert = 0,
dbl1 = 1,
dblException = 1,
dblCritical = 1,
dbl2 = 2,
dblMajor = 2,
dbl3 = 3,
dblCall = 3,
dblSecondary = 3,
dblHead = 3,
dbl4 = 4,
dblWarning = 4,
dbl5 = 5,
dblInfo = 5,
dbl6 = 6,
dblIn = 6,
dblOut = 6,
dbl7 = 7,
dbl8 = 8,
dblTrace = 8,
dbl9 = 9,
dblAccessory = 9,
dbl10 = 10,
dblDebug = 42,
dbl100 = 100,
dblDump = 100,
dblTest = 1337
};
/* -------------------------------------------------------------------------- */
#define AKANTU_LOCATION "(" << __func__ << "(): " << __FILE__ << ":" << __LINE__ << ")"
/* -------------------------------------------------------------------------- */
namespace debug {
void setDebugLevel(const DebugLevel & level);
const DebugLevel & getDebugLevel();
void initSignalHandler();
std::string demangle(const char * symbol);
std::string exec(std::string cmd);
void printBacktrace(int sig);
void exit(int status) __attribute__ ((noreturn));
/* -------------------------------------------------------------------------- */
/// exception class that can be thrown by akantu
class Exception : public std::exception {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
//! full constructor
Exception(std::string info, std::string file, unsigned int line) :
_info(info), _file(file), _line(line) { }
//! destructor
virtual ~Exception() throw() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual const char* what() const throw() {
return _info.c_str();
}
virtual const char* info() const throw() {
std::stringstream stream;
stream << "akantu::Exception"
<< " : " << _info
<< " [" << _file << ":" << _line << "]";
return stream.str().c_str();
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// exception description and additionals
std::string _info;
/// file it is thrown from
std::string _file;
/// ligne it is thrown from
unsigned int _line;
};
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const Exception & _this)
{
stream << _this.what();
return stream;
}
/* -------------------------------------------------------------------------- */
class Debugger {
public:
Debugger();
virtual ~Debugger();
void exit(int status) __attribute__ ((noreturn));
void throwException(const std::string & info,
const std::string & file,
unsigned int line,
__attribute__((unused)) bool silent,
__attribute__((unused)) const std::string & location)
const throw(akantu::debug::Exception) __attribute__ ((noreturn));
void printMessage(const std::string & prefix,
const DebugLevel & level,
const std::string & info) const;
void setOutStream(std::ostream & out) { cout = &out; }
std::ostream & getOutStream() { return *cout; }
public:
void setParallelContext(int rank, int size);
void setDebugLevel(const DebugLevel & level);
const DebugLevel & getDebugLevel() const;
void setLogFile(const std::string & filename);
std::ostream & getOutputStream();
inline bool testLevel(const DebugLevel & level) const {
return (this->level >= (level));
}
void printBacktrace(bool on_off) {
this->print_backtrace = on_off;
}
private:
std::string parallel_context;
std::ostream * cout;
bool file_open;
DebugLevel level;
bool print_backtrace;
};
extern Debugger debugger;
}
/* -------------------------------------------------------------------------- */
#define AKANTU_STRINGSTREAM_IN(_str, _sstr); \
do { \
std::stringstream _dbg_s_info; \
_dbg_s_info << _sstr; \
_str = _dbg_s_info.str(); \
} while(0)
/* -------------------------------------------------------------------------- */
#define AKANTU_EXCEPTION(info) \
AKANTU_EXCEPTION_(info, false)
#define AKANTU_SILENT_EXCEPTION(info) \
AKANTU_EXCEPTION_(info, true)
#define AKANTU_EXCEPTION_(info, silent) \
do { \
std::stringstream _dbg_str; \
_dbg_str << info; \
std::stringstream _dbg_loc; _dbg_loc << AKANTU_LOCATION; \
::akantu::debug::debugger.throwException(_dbg_str.str(), \
__FILE__, \
__LINE__, \
silent, \
_dbg_loc.str()); \
} while(0)
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_NDEBUG
#define AKANTU_DEBUG_TEST(level) (false)
#define AKANTU_DEBUG_LEVEL_IS_TEST() (::akantu::debug::debugger.testLevel(dblTest))
#define AKANTU_DEBUG(level,info)
#define AKANTU_DEBUG_(pref,level,info)
#define AKANTU_DEBUG_IN()
#define AKANTU_DEBUG_OUT()
#define AKANTU_DEBUG_INFO(info)
#define AKANTU_DEBUG_WARNING(info)
#define AKANTU_DEBUG_TRACE(info)
#define AKANTU_DEBUG_ASSERT(test,info)
#define AKANTU_DEBUG_ERROR(info) AKANTU_EXCEPTION(info)
#define AKANTU_DEBUG_TO_IMPLEMENT() ::akantu::debug::debugger.exit(EXIT_FAILURE)
/* -------------------------------------------------------------------------- */
#else
#define AKANTU_DEBUG(level, info) \
AKANTU_DEBUG_(" ",level, info)
#define AKANTU_DEBUG_(pref, level, info) \
do { \
std::string _dbg_str; \
AKANTU_STRINGSTREAM_IN(_dbg_str, info << " " << AKANTU_LOCATION); \
::akantu::debug::debugger.printMessage(pref, level, _dbg_str); \
} while(0)
#define AKANTU_DEBUG_TEST(level) \
(::akantu::debug::debugger.testLevel(level))
#define AKANTU_DEBUG_LEVEL_IS_TEST() \
(::akantu::debug::debugger.testLevel(dblTest))
#define AKANTU_DEBUG_IN() \
AKANTU_DEBUG_("==>", ::akantu::dblIn, __func__ << "()")
#define AKANTU_DEBUG_OUT() \
AKANTU_DEBUG_("<==", ::akantu::dblOut, __func__ << "()")
#define AKANTU_DEBUG_INFO(info) \
AKANTU_DEBUG_("---", ::akantu::dblInfo, info)
#define AKANTU_DEBUG_WARNING(info) \
AKANTU_DEBUG_("/!\\", ::akantu::dblWarning, info)
#define AKANTU_DEBUG_TRACE(info) \
AKANTU_DEBUG_(">>>", ::akantu::dblTrace, info)
#define AKANTU_DEBUG_ASSERT(test,info) \
do { \
if (!(test)) { \
AKANTU_DEBUG_("!!! ", ::akantu::dblAssert, "assert [" << #test << "] " \
<< info); \
::akantu::debug::debugger.exit(EXIT_FAILURE); \
} \
} while(0)
#define AKANTU_DEBUG_ERROR(info) \
do { \
AKANTU_DEBUG_("!!! ", ::akantu::dblError, info); \
::akantu::debug::debugger.exit(EXIT_FAILURE); \
} while(0)
#define AKANTU_DEBUG_TO_IMPLEMENT() \
AKANTU_DEBUG_ERROR(__func__ << " : not implemented yet !")
#endif // AKANTU_NDEBUG
/* -------------------------------------------------------------------------- */
}
#endif /* __AKANTU_ERROR_HH__ */
diff --git a/src/common/aka_event_handler_manager.hh b/src/common/aka_event_handler_manager.hh
index 5cd15cf8f..737b557b8 100644
--- a/src/common/aka_event_handler_manager.hh
+++ b/src/common/aka_event_handler_manager.hh
@@ -1,95 +1,96 @@
/**
* @file aka_event_handler_manager.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Aug 23 2012
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Dec 16 2015
*
* @brief Base of Event Handler classes
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_EVENT_HANDLER_MANAGER_HH__
#define __AKANTU_AKA_EVENT_HANDLER_MANAGER_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#include <set>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
template<class EventHandler>
class EventHandlerManager {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
virtual ~EventHandlerManager() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// register a new EventHandler to the Manager. The register object
/// will then be informed about the events the manager observes.
void registerEventHandler(EventHandler & event_handler) {
event_handlers.insert(&event_handler);
}
/// unregister a EventHandler object. This object will not be
/// notified anymore about the events this manager observes.
void unregisterEventHandler(EventHandler & event_handler) {
event_handlers.erase(&event_handler);
}
/// Notify all the registered EventHandlers about the event that just occured.
template<class Event>
void sendEvent(const Event & event) {
typename std::set<EventHandler *>::iterator it = event_handlers.begin();
typename std::set<EventHandler *>::iterator end = event_handlers.end();
for(;it != end; ++it)
(*it)->sendEvent(event);
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// list of the event handlers
std::set<EventHandler *> event_handlers;
};
__END_AKANTU__
#endif /* __AKANTU_AKA_EVENT_HANDLER_MANAGER_HH__ */
diff --git a/src/common/aka_extern.cc b/src/common/aka_extern.cc
index c9230ee0c..d9370a740 100644
--- a/src/common/aka_extern.cc
+++ b/src/common/aka_extern.cc
@@ -1,103 +1,104 @@
/**
* @file aka_extern.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
- * @date last modification: Thu Apr 03 2014
+ * @date last modification: Thu Nov 19 2015
*
* @brief initialisation of all global variables
* to insure the order of creation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_array.hh"
#include "aka_math.hh"
#include "aka_random_generator.hh"
#include "parser.hh"
#include "cppargparse.hh"
#include "static_solver.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <limits>
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_DEBUG_TOOLS)
# include "aka_debug_tools.hh"
#endif
__BEGIN_AKANTU__
/** \todo write function to get this
* values from the environment or a config file
*/
/* -------------------------------------------------------------------------- */
/* error.hpp variables */
/* -------------------------------------------------------------------------- */
namespace debug {
/// standard output for debug messages
std::ostream *_akantu_debug_cout = &std::cerr;
/// standard output for normal messages
std::ostream & _akantu_cout = std::cout;
/// parallel context used in debug messages
std::string _parallel_context = "";
Debugger debugger;
#if defined(AKANTU_DEBUG_TOOLS)
DebugElementManager element_manager;
#endif
}
/// Paser for commandline arguments
::cppargparse::ArgumentParser static_argparser;
/// Parser containing the information parsed by the input file given to initFull
Parser static_parser;
bool Parser::permissive_parser = false;
Real Math::tolerance = std::numeric_limits<Real>::epsilon();
const UInt _all_dimensions = UInt(-1);
const Array<UInt> empty_filter(0, 1, "empty_filter");
template<> long int RandGenerator<Real>::_seed = 0;
template<> long int RandGenerator<bool>::_seed = 0; // useless just defined due to a template instantiation
template<> long int RandGenerator<UInt>::_seed = 0;
template<> long int RandGenerator<Int>::_seed = 0;
#if not defined(_WIN32)
template<> long int Rand48Generator<Real>::_seed = 0;
#endif
/* -------------------------------------------------------------------------- */
UInt StaticSolver::nb_references = 0;
StaticSolver * StaticSolver::static_solver = NULL;
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/common/aka_fwd.hh b/src/common/aka_fwd.hh
index d5c0c4a99..601bb534b 100644
--- a/src/common/aka_fwd.hh
+++ b/src/common/aka_fwd.hh
@@ -1,70 +1,71 @@
/**
* @file aka_fwd.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Tue Aug 18 2015
*
* @brief File containing forward declarations in akantu.
* This file helps if circular #include would be needed because two classes
* refer both to each other. This file usually does not need any modification.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_FWD_HH__
#define __AKANTU_FWD_HH__
namespace cppargparse {
class ArgumentParser;
}
namespace akantu {
// forward declaration
template <int dim, class model_type>
struct ContactData;
template<typename T> class Matrix;
template<typename T> class Vector;
template<typename T> class Tensor3;
template<typename T, bool is_scal = is_scalar<T>::value > class Array;
template <class T> class SpatialGrid;
// Model element
template <class ModelPolicy> class ModelElement;
extern const Array<UInt> empty_filter;
class Parser;
class ParserSection;
extern Parser static_parser;
extern cppargparse::ArgumentParser static_argparser;
}
#endif /* __AKANTU_FWD_HH__ */
diff --git a/src/common/aka_geometry.cc b/src/common/aka_geometry.cc
index 84571612e..0337f1d9f 100644
--- a/src/common/aka_geometry.cc
+++ b/src/common/aka_geometry.cc
@@ -1,56 +1,57 @@
/**
* @file aka_geometry.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Tue May 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief geometric operations
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_geometry.hh"
__BEGIN_AKANTU__
using std::cout;
using std::endl;
/*! \param p - A constant reference to the first point that defines the line segment.
* \param q - A constant reference to the second point that defines the line segment.
* \param r - A constant reference to the point for which the predicate is computed.
* \return A double, being -1.0 if the point lines on one side of the line and 1.0 if it lies
* on the other side.
*/
Real left_turn(const Point<2>& p, const Point<2>& q, const Point<2>& r) {
if(((q[0]-p[0]) * (r[1]-p[1])) > ((r[0]-p[0]) * (q[1]-p[1])))
return 1.;
else
return -1.;
}
__END_AKANTU__
diff --git a/src/common/aka_geometry.hh b/src/common/aka_geometry.hh
index c95ff0de4..9a6bb297c 100644
--- a/src/common/aka_geometry.hh
+++ b/src/common/aka_geometry.hh
@@ -1,365 +1,365 @@
/**
* @file aka_geometry.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Wed Dec 16 2015
*
* @brief geometric operations
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_GEOMETRY_HH__
#define __AKANTU_GEOMETRY_HH__
#include <iostream>
#include <tuple>
#include "aka_point.hh"
#include "aka_plane.hh"
#include "aka_math.hh"
__BEGIN_AKANTU__
// predicates
// combined tolerance test, from Christer Ericson
template <typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
equal(T x, T y)
{ return x == y; }
Real left_turn(const Point<2>& p, const Point<2>& q, const Point<2>& r);
// closest point computations
//! Computes the closest point laying on a segment to a point
/*! Given segment \c ab and point \c c, computes closest point \c d on ab.
* Also returns \c t for the position of the point: a + t*(b - a)
*/
template <int d, typename T>
Point<d,T> closest_point_to_segment(const Point<d,T>& c,
const Point<d,T>& a,
const Point<d,T>& b) {
Point<d,T> ab = b - a;
// project c onto ab, computing parameterized position d(t) = a + t*(b – a)
T t = (c - a)*ab / sqrt(ab*ab);
// if outside segment, clamp t (and therefore d) to the closest endpoint
if (t < 0.)
t = 0.;
else if (t > 1.)
t = 1.;
// compute projected position from the clamped t
return a + t * ab;
}
//! Predicate that checks if a point has a projection on a line segment
/*! Given segment \c ab and point \c c, checks if the point has a projection in the segment.
*/
template <int d, typename T>
bool has_projection(const Point<d,T>& c,
const Point<d,T>& a,
const Point<d,T>& b) {
Point<d,T> ab = b - a;
// project c onto ab, computing parameterized position d(t) = a + t*(b – a)
T t = (c - a)*ab / (ab*ab);
return t > 0. && t < 1.;
}
//! Tests if a point has a projection to a triangle
/*! This function uses the concept of Voronoi regions to determine
* if a point has a projection within a triangle defined by points
* \c a, \c b, and \c c.
*/
template <typename T>
bool point_has_projection_to_triangle(const Point<3,T>& p,
const Point<3,T>& a,
const Point<3,T>& b,
const Point<3,T>& c) {
typedef Point<3,T> point_type;
// obtain plane of the triangle
Plane pi(a,b,c);
// get point in the plane closest to p
point_type q = closest_point_to_plane(p,pi);
// return if point is within the triangle
if (is_point_in_triangle(q, a, b, c))
return true;
return false;
}
//! Tests if point P lies inside a triangle
/*! The triangle is defined by points \c a, \c b and \c c.
*/
template <typename T>
bool is_point_in_triangle(const Point<3,T>& p,
const Point<3,T>& a,
const Point<3,T>& b,
const Point<3,T>& c) {
typedef Point<3,T> point_type;
point_type v0 = b-a, v1 = c-a, v2 = p-a;
Real d00 = v0*v0;
Real d01 = v0*v1;
Real d11 = v1*v1;
Real d20 = v2*v0;
Real d21 = v2*v1;
Real denom = d00*d11 - d01*d01;
// compute parametric coordinates
Real v = (d11 * d20 - d01 * d21) / denom;
Real w = (d00 * d21 - d01 * d20) / denom;
return v >= 0. && w >= 0. && v + w <= 1.;
}
//! Compute the closest point to a triangle
/*! This function uses the concept of Voronoi regions to determine
* the closest point \c p to a triangle defined by points \c a, \c b
* \c c.
*/
template <typename T>
Point<3,T> closest_point_to_triangle(const Point<3,T>& p,
const Point<3,T>& a,
const Point<3,T>& b,
const Point<3,T>& c) {
typedef Point<3,T> point_type;
// check if P in vertex region outside A
point_type ab = b - a;
point_type ac = c - a;
point_type ap = p - a;
// compute scalar products
T d1 = ab * ap;
T d2 = ac * ap;
if (d1 <= 0. && d2 <= 0.)
return a; // barycentric coordinates (1,0,0)
// check if P in vertex region outside B
point_type bp = p - b;
T d3 = ab * bp;
T d4 = ac * bp;
if (d3 >= 0.0f && d4 <= d3)
return b; // barycentric coordinates (0,1,0)
// check if P in edge region of AB, if so return projection of P onto AB
T vc = d1*d4 - d3*d2;
if (vc <= 0. && d1 >= 0. && d3 <= 0.) {
T v = d1 / (d1 - d3);
return a + v * ab; // barycentric coordinates (1-v,v,0)
}
// check if P in vertex region outside C
point_type cp = p - c;
T d5 = ab * cp;
T d6 = ac * cp;
if (d6 >= 0.0f && d5 <= d6)
return c; // barycentric coordinates (0,0,1)
// check if P in edge region of AC, if so return projection of P onto AC
T vb = d5*d2 - d1*d6;
if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
T w = d2 / (d2 - d6);
return a + w * ac; // barycentric coordinates (1-w,0,w)
}
// Check if P in edge region of BC, if so return projection of P onto BC
T va = d3*d6 - d5*d4;
if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
T w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
return b + w * (c - b); // barycentric coordinates (0,1-w,w)
}
// P inside face region. Compute Q through its barycentric coordinates (u,v,w)
T denom = 1.0f / (va + vb + vc);
T v = vb * denom;
T w = vc * denom;
return a + ab*v + ac*w; // = u*a + v*b + w*c, u = va*denom = 1.0f - v - w
}
template <typename T>
Point<3,T> closest_point_to_plane(const Point<3,T>& q, const Plane& p) {
typedef Point<3,T> point_type;
const point_type& n = p.normal();
T t = (n*q - p.distance()) / (n*n);
return q - t * n;
}
//! Compute the closest point to a triangle
/*! Obtains the plane of the triangle and checks if the point lies inside the
* triangle. If not, it computes the closest point to each of the triangle
* edges.
*/
template <typename T>
Point<3,T> naive_closest_point_to_triangle(const Point<3,T>& p,
const Point<3,T>& a,
const Point<3,T>& b,
const Point<3,T>& c) {
typedef Point<3,T> point_type;
// obtain plane of the triangle
Plane pi(a,b,c);
// get point in the plane closest to p
point_type q = closest_point_to_plane(p,pi);
// return if point is within the triangle
if (is_point_in_triangle(q, a, b, c))
return q;
// else get the closest point taking into account all edges
// first edge
q = closest_point_to_segment(p, a, b);
T d = (q-p).sq_norm();
// second edge
point_type r = closest_point_to_segment(p, b, c);
T d2 = (r-p).sq_norm();
if (d2 < d) {
q = r;
d = d2;
}
// third edge
r = closest_point_to_segment(p,c,a);
d2 = (r-p).sq_norm();
if (d2 < d)
q = r;
// return closest point
return q;
}
// intersect point p with velocity v with plane
// the function returns collision time and point of contact
// this function does not consider acceleration
template <typename T>
std::tuple<Real, Point<3,T> >
moving_point_against_plane(const Point<3,T>& p, const Point<3,T>& v, Plane& pi) {
typedef Point<3,T> point_type;
// compute distance of point to plane
Real dist = pi.normal()*p - pi.distance();
// if point already in the plane
if (std::abs(dist) <= 1e-10)
return std::make_tuple(0., p);
else {
Real denom = pi.normal()*v;
// no intersection as poin moving parallel to or away from plane
if (denom * dist >= 0.)
return std::make_tuple(inf, point_type());
// point moving towards the plane
else {
// point is moving towards the plane
Real t = -dist/denom;
return std::make_tuple(t, p + t*v);
}
}
}
template <int dim, typename T>
std::tuple<Real, Point<dim,T> >
moving_point_against_point(const Point<dim,T>& s1, const Point<dim,T>& s2, /* point centers */
const Point<dim,T>& v1, const Point<dim,T>& v2) /* point velocities */ {
typedef Point<dim,T> point_type;
typedef typename Point<dim,T>::value_type value_type;
// vector between points
point_type s = s2 - s1;
// relative motion of s1 with respect to stationary s0
point_type v = v2 - v1;
value_type c = s*s;
// if points within tolerance
if (equal(s.sq_norm(), value_type()))
return std::make_tuple(value_type(), s1);
value_type epsilon = 2*std::numeric_limits<T>::epsilon();;
value_type a = v*v;
// if points not moving relative to each other
if (a < epsilon)
return std::make_tuple(inf, point_type());
value_type b = v*s;
// if points not moving towards each other
if (b >= 0.)
return std::make_tuple(inf, point_type());
value_type d = b*b - a*c;
// if no real-valued root (d < 0), points do not intersect
if (d >= 0.) {
value_type ts = (-b - sqrt(d))/a;
point_type q = s1+v1*ts;
return std::make_tuple(ts, q);
}
return std::make_tuple(inf, point_type());
}
__END_AKANTU__
#endif /* __AKANTU_GEOMETRY_HH__ */
diff --git a/src/common/aka_grid_dynamic.hh b/src/common/aka_grid_dynamic.hh
index 7bf69449c..c1758cf2f 100644
--- a/src/common/aka_grid_dynamic.hh
+++ b/src/common/aka_grid_dynamic.hh
@@ -1,506 +1,507 @@
/**
* @file aka_grid_dynamic.hh
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
- * @date last modification: Fri Mar 21 2014
+ * @date last modification: Sat Sep 26 2015
*
* @brief Grid that is auto balanced
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
#include "aka_types.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_GRID_DYNAMIC_HH__
#define __AKANTU_AKA_GRID_DYNAMIC_HH__
__BEGIN_AKANTU__
class Mesh;
template<typename T>
class SpatialGrid {
public:
SpatialGrid(UInt dimension) : dimension(dimension),
spacing(dimension),
center(dimension),
lower(dimension),
upper(dimension),
empty_cell() {}
SpatialGrid(UInt dimension,
const Vector<Real> & spacing,
const Vector<Real> & center) : dimension(dimension),
spacing(spacing),
center(center),
lower(dimension),
upper(dimension),
empty_cell() {
for (UInt i = 0; i < dimension; ++i) {
lower(i) = std::numeric_limits<Real>::max();
upper(i) = - std::numeric_limits<Real>::max();
}
}
virtual ~SpatialGrid() {};
class neighbor_cells_iterator;
class cells_iterator;
class CellID {
public:
CellID() : ids() {}
CellID(UInt dimention) : ids(dimention) {}
void setID(UInt dir, Int id) { ids(dir) = id; }
Int getID(UInt dir) const { return ids(dir); }
bool operator<(const CellID & id) const {
return std::lexicographical_compare(ids.storage(), ids.storage() + ids.size(),
id.ids.storage(), id.ids.storage() + id.ids.size());
}
bool operator==(const CellID & id) const {
return std::equal(ids.storage(), ids.storage() + ids.size(),
id.ids.storage());
}
bool operator!=(const CellID & id) const {
return !(operator==(id));
}
private:
friend class neighbor_cells_iterator;
friend class cells_iterator;
Vector<Int> ids;
};
/* -------------------------------------------------------------------------- */
class Cell {
public:
typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
Cell() : id(), data() { }
Cell(const CellID &cell_id) : id(cell_id), data() { }
bool operator==(const Cell & cell) const { return id == cell.id; }
bool operator!=(const Cell & cell) const { return id != cell.id; }
Cell & add(const T & d) { data.push_back(d); return *this; }
iterator begin() { return data.begin(); }
const_iterator begin() const { return data.begin(); }
iterator end() { return data.end(); }
const_iterator end() const { return data.end(); }
// #if not defined(AKANTU_NDEBUG)
// Cell & add(const T & d, const Vector<Real> & pos) {
// data.push_back(d); positions.push_back(pos); return *this;
// }
// typedef typename std::vector< Vector<Real> >::const_iterator position_iterator;
// position_iterator begin_pos() const { return positions.begin(); }
// position_iterator end_pos() const { return positions.end(); }
// #endif
private:
CellID id;
std::vector<T> data;
// #if not defined(AKANTU_NDEBUG)
// std::vector< Vector<Real> > positions;
// #endif
};
private:
typedef std::map<CellID, Cell> cells_container;
public:
const Cell & getCell(const CellID & cell_id) const {
typename cells_container::const_iterator it = cells.find(cell_id);
if(it != cells.end()) return it->second;
else return empty_cell;
}
typename Cell::iterator beginCell(const CellID & cell_id) {
typename cells_container::iterator it = cells.find(cell_id);
if(it != cells.end()) return it->second.begin();
else return empty_cell.begin();
}
typename Cell::iterator endCell(const CellID & cell_id) {
typename cells_container::iterator it = cells.find(cell_id);
if(it != cells.end()) return it->second.end();
else return empty_cell.end();
}
typename Cell::const_iterator beginCell(const CellID & cell_id) const {
typename cells_container::const_iterator it = cells.find(cell_id);
if(it != cells.end()) return it->second.begin();
else return empty_cell.begin();
}
typename Cell::const_iterator endCell(const CellID & cell_id) const {
typename cells_container::const_iterator it = cells.find(cell_id);
if(it != cells.end()) return it->second.end();
else return empty_cell.end();
}
class neighbor_cells_iterator : private std::iterator<std::forward_iterator_tag, UInt> {
public:
neighbor_cells_iterator(const CellID & cell_id, bool end) :
cell_id(cell_id),
position(cell_id.ids.size(), end ? 1 : -1) {
this->updateIt();
if(end) this->it++;
}
neighbor_cells_iterator& operator++() {
UInt i = 0;
for (; i < position.size() && position(i) == 1; ++i);
if(i == position.size()) ++it;
else {
for (UInt j = 0; j < i; ++j) position(j) = -1;
position(i)++;
updateIt();
}
return *this;
}
neighbor_cells_iterator operator++(int) { neighbor_cells_iterator tmp(*this); operator++(); return tmp; };
bool operator==(const neighbor_cells_iterator& rhs) const { return cell_id == rhs.cell_id && it == rhs.it; };
bool operator!=(const neighbor_cells_iterator& rhs) const { return ! operator==(rhs); };
CellID operator*() const {
CellID cur_cell_id(cell_id);
cur_cell_id.ids += position;
return cur_cell_id;
};
private:
void updateIt() {
it = 0;
for (UInt i = 0; i < position.size(); ++i) it = it * 3 + (position(i) + 1);
}
private:
/// central cell id
const CellID & cell_id;
// number representing the current neighbor in base 3;
UInt it;
Vector<Int> position;
};
class cells_iterator : private std::iterator<std::forward_iterator_tag, CellID> {
public:
cells_iterator(typename std::map<CellID, Cell>::const_iterator it) :
it(it) { }
cells_iterator & operator++() {
this->it++;
return *this;
}
cells_iterator operator++(int) {cells_iterator tmp(*this); operator++(); return tmp; };
bool operator==(const cells_iterator& rhs) const { return it == rhs.it; };
bool operator!=(const cells_iterator& rhs) const { return ! operator==(rhs); };
CellID operator*() const {
CellID cur_cell_id(this->it->first);
return cur_cell_id;
};
private:
/// map iterator
typename std::map<CellID, Cell>::const_iterator it;
};
public:
template<class vector_type>
Cell & insert(const T & d, const vector_type & position) {
CellID cell_id = getCellID(position);
typename cells_container::iterator it = cells.find(cell_id);
if(it == cells.end()) {
Cell cell(cell_id);
// #if defined(AKANTU_NDEBUG)
Cell & tmp = (cells[cell_id] = cell).add(d);
// #else
// Cell & tmp = (cells[cell_id] = cell).add(d, position);
// #endif
for (UInt i = 0; i < dimension; ++i) {
Real posl = center(i) + cell_id.getID(i) * spacing(i);
Real posu = posl + spacing(i);
if(posl < lower(i)) lower(i) = posl;
if(posu > upper(i)) upper(i) = posu;
}
return tmp;
} else {
// #if defined(AKANTU_NDEBUG)
return it->second.add(d);
// #else
// return it->second.add(d, position);
// #endif
}
}
inline neighbor_cells_iterator beginNeighborCells(const CellID & cell_id) const {
return neighbor_cells_iterator(cell_id, false);
}
inline neighbor_cells_iterator endNeighborCells(const CellID & cell_id) const {
return neighbor_cells_iterator(cell_id, true);
}
inline cells_iterator beginCells() const {
typename std::map<CellID, Cell>::const_iterator begin = this->cells.begin();
return cells_iterator(begin);
}
inline cells_iterator endCells() const {
typename std::map<CellID, Cell>::const_iterator end = this->cells.end();
return cells_iterator(end);
}
template<class vector_type>
CellID getCellID(const vector_type & position) const {
CellID cell_id(dimension);
for (UInt i = 0; i < dimension; ++i) {
cell_id.setID(i, getCellID(position(i), i));
}
return cell_id;
}
void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
std::streamsize prec = stream.precision();
std::ios_base::fmtflags ff = stream.flags();
stream.setf (std::ios_base::showbase);
stream.precision(5);
stream << space << "SpatialGrid<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
stream << space << " + dimension : " << this->dimension << std::endl;
stream << space << " + lower bounds : {";
for (UInt i = 0; i < lower.size(); ++i) { if(i != 0) stream << ", "; stream << lower(i); };
stream << "}" << std::endl;
stream << space << " + upper bounds : {";
for (UInt i = 0; i < upper.size(); ++i) { if(i != 0) stream << ", "; stream << upper(i); };
stream << "}" << std::endl;
stream << space << " + spacing : {";
for (UInt i = 0; i < spacing.size(); ++i) { if(i != 0) stream << ", "; stream << spacing(i); };
stream << "}" << std::endl;
stream << space << " + center : {";
for (UInt i = 0; i < center.size(); ++i) { if(i != 0) stream << ", "; stream << center(i); };
stream << "}" << std::endl;
stream << space << " + nb_cells : " << this->cells.size() << "/";
Vector<Real> dist(this->dimension);
dist = upper;
dist -= lower;
for (UInt i = 0; i < this->dimension; ++i) {
dist(i) /= spacing(i);
}
UInt nb_cells = std::ceil(dist(0));
for (UInt i = 1; i < this->dimension; ++i) {
nb_cells *= std::ceil(dist(i));
}
stream << nb_cells << std::endl;
stream << space << "]" << std::endl;
stream.precision(prec);
stream.flags(ff);
}
void saveAsMesh(Mesh & mesh) const;
private:
/* -------------------------------------------------------------------------- */
inline UInt getCellID(Real position, UInt direction) const {
AKANTU_DEBUG_ASSERT(direction < center.size(), "The direction asked ("
<< direction << ") is out of range " << center.size());
Real dist_center = position - center(direction);
Int id = std::floor(dist_center / spacing(direction));
//if(dist_center < 0) id--;
return id;
}
friend class GridSynchronizer;
public:
AKANTU_GET_MACRO(LowerBounds, lower, const Vector<Real> &);
AKANTU_GET_MACRO(UpperBounds, upper, const Vector<Real> &);
AKANTU_GET_MACRO(Spacing, spacing, const Vector<Real> &);
protected:
UInt dimension;
cells_container cells;
Vector<Real> spacing;
Vector<Real> center;
Vector<Real> lower;
Vector<Real> upper;
Cell empty_cell;
};
/// standard output stream operator
template<typename T>
inline std::ostream & operator <<(std::ostream & stream, const SpatialGrid<T> & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#include "mesh.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<typename T>
void SpatialGrid<T>::saveAsMesh(Mesh & mesh) const {
Array<Real> & nodes = const_cast<Array<Real> &>(mesh.getNodes());
ElementType type;
switch(dimension) {
case 1: type = _segment_2; break;
case 2: type = _quadrangle_4; break;
case 3: type = _hexahedron_8; break;
}
mesh.addConnectivityType(type);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(type));
Array<UInt> & uint_data = *mesh.getDataPointer<UInt>("tag_1", type);
typename cells_container::const_iterator it = cells.begin();
typename cells_container::const_iterator end = cells.end();
Vector<Real> pos(dimension);
UInt global_id = 0;
for (;it != end; ++it, ++global_id) {
UInt cur_node = nodes.getSize();
UInt cur_elem = connectivity.getSize();
const CellID & cell_id = it->first;
for (UInt i = 0; i < dimension; ++i) pos(i) = center(i) + cell_id.getID(i) * spacing(i);
nodes.push_back(pos);
for (UInt i = 0; i < dimension; ++i) pos(i) += spacing(i);
nodes.push_back(pos);
connectivity.push_back(cur_node);
switch(dimension) {
case 1:
connectivity(cur_elem, 1) = cur_node + 1;
break;
case 2:
pos(0) -= spacing(0); nodes.push_back(pos);
pos(0) += spacing(0); pos(1) -= spacing(1); nodes.push_back(pos);
connectivity(cur_elem, 1) = cur_node + 3;
connectivity(cur_elem, 2) = cur_node + 1;
connectivity(cur_elem, 3) = cur_node + 2;
break;
case 3:
pos(1) -= spacing(1); pos(2) -= spacing(2); nodes.push_back(pos);
pos(1) += spacing(1); nodes.push_back(pos);
pos(0) -= spacing(0); nodes.push_back(pos);
pos(1) -= spacing(1); pos(2) += spacing(2); nodes.push_back(pos);
pos(0) += spacing(0); nodes.push_back(pos);
pos(0) -= spacing(0); pos(1) += spacing(1); nodes.push_back(pos);
connectivity(cur_elem, 1) = cur_node + 2;
connectivity(cur_elem, 2) = cur_node + 3;
connectivity(cur_elem, 3) = cur_node + 4;
connectivity(cur_elem, 4) = cur_node + 5;
connectivity(cur_elem, 5) = cur_node + 6;
connectivity(cur_elem, 6) = cur_node + 1;
connectivity(cur_elem, 7) = cur_node + 7;
break;
}
uint_data.push_back(global_id);
}
// #if not defined(AKANTU_NDEBUG)
// mesh.addConnectivityType(_point_1);
// Array<UInt> & connectivity_pos = const_cast<Array<UInt> &>(mesh.getConnectivity(_point_1));
// Array<UInt> & uint_data_pos = *mesh.getDataPointer<UInt>( "tag_1", _point_1);
// Array<UInt> & uint_data_pos_ghost = *mesh.getDataPointer<UInt>("tag_0", _point_1);
// it = cells.begin();
// global_id = 0;
// for (;it != end; ++it, ++global_id) {
// typename Cell::position_iterator cell_it = it->second.begin_pos();
// typename Cell::const_iterator cell_it_cont = it->second.begin();
// typename Cell::position_iterator cell_end = it->second.end_pos();
// for (;cell_it != cell_end; ++cell_it, ++cell_it_cont) {
// nodes.push_back(*cell_it);
// connectivity_pos.push_back(nodes.getSize()-1);
// uint_data_pos.push_back(global_id);
// uint_data_pos_ghost.push_back(cell_it_cont->ghost_type==_ghost);
// }
// }
// #endif
}
__END_AKANTU__
#endif /* __AKANTU_AKA_GRID_DYNAMIC_HH__ */
diff --git a/src/common/aka_math.cc b/src/common/aka_math.cc
index 71aedd3de..e2614adcd 100644
--- a/src/common/aka_math.cc
+++ b/src/common/aka_math.cc
@@ -1,233 +1,234 @@
/**
* @file aka_math.cc
*
- * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
- * @author Peter Spijker <peter.spijker@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
+ * @author Peter Spijker <peter.spijker@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Wed Aug 04 2010
- * @date last modification: Thu Mar 27 2014
+ * @date last modification: Fri May 15 2015
*
* @brief Implementation of the math toolbox
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_math.hh"
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
void Math::matrix_vector(UInt m, UInt n,
const Array<Real> & A,
const Array<Real> & x,
Array<Real> & y,
Real alpha) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(A.getSize() == x.getSize(),
"The vector A(" << A.getID()
<< ") and the vector x(" << x.getID()
<< ") must have the same size");
AKANTU_DEBUG_ASSERT(A.getNbComponent() == m * n,
"The vector A(" << A.getID()
<< ") has the good number of component.");
AKANTU_DEBUG_ASSERT(x.getNbComponent() == n,
"The vector x(" << x.getID()
<< ") do not the good number of component.");
AKANTU_DEBUG_ASSERT(y.getNbComponent() == n,
"The vector y(" << y.getID()
<< ") do not the good number of component.");
UInt nb_element = A.getSize();
UInt offset_A = A.getNbComponent();
UInt offset_x = x.getNbComponent();
y.resize(nb_element);
Real * A_val = A.storage();
Real * x_val = x.storage();
Real * y_val = y.storage();
for (UInt el = 0; el < nb_element; ++el) {
matrix_vector(m, n, A_val, x_val, y_val, alpha);
A_val += offset_A;
x_val += offset_x;
y_val += offset_x;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Math::matrix_matrix(UInt m, UInt n, UInt k,
const Array<Real> & A,
const Array<Real> & B,
Array<Real> & C,
Real alpha) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(A.getSize() == B.getSize(),
"The vector A(" << A.getID()
<< ") and the vector B(" << B.getID()
<< ") must have the same size");
AKANTU_DEBUG_ASSERT(A.getNbComponent() == m * k,
"The vector A(" << A.getID()
<< ") has the good number of component.");
AKANTU_DEBUG_ASSERT(B.getNbComponent() == k * n ,
"The vector B(" << B.getID()
<< ") do not the good number of component.");
AKANTU_DEBUG_ASSERT(C.getNbComponent() == m * n,
"The vector C(" << C.getID()
<< ") do not the good number of component.");
UInt nb_element = A.getSize();
UInt offset_A = A.getNbComponent();
UInt offset_B = B.getNbComponent();
UInt offset_C = C.getNbComponent();
C.resize(nb_element);
Real * A_val = A.storage();
Real * B_val = B.storage();
Real * C_val = C.storage();
for (UInt el = 0; el < nb_element; ++el) {
matrix_matrix(m, n, k, A_val, B_val, C_val, alpha);
A_val += offset_A;
B_val += offset_B;
C_val += offset_C;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Math::matrix_matrixt(UInt m, UInt n, UInt k,
const Array<Real> & A,
const Array<Real> & B,
Array<Real> & C,
Real alpha) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(A.getSize() == B.getSize(),
"The vector A(" << A.getID()
<< ") and the vector B(" << B.getID()
<< ") must have the same size");
AKANTU_DEBUG_ASSERT(A.getNbComponent() == m * k,
"The vector A(" << A.getID()
<< ") has the good number of component.");
AKANTU_DEBUG_ASSERT(B.getNbComponent() == k * n ,
"The vector B(" << B.getID()
<< ") do not the good number of component.");
AKANTU_DEBUG_ASSERT(C.getNbComponent() == m * n,
"The vector C(" << C.getID()
<< ") do not the good number of component.");
UInt nb_element = A.getSize();
UInt offset_A = A.getNbComponent();
UInt offset_B = B.getNbComponent();
UInt offset_C = C.getNbComponent();
C.resize(nb_element);
Real * A_val = A.storage();
Real * B_val = B.storage();
Real * C_val = C.storage();
for (UInt el = 0; el < nb_element; ++el) {
matrix_matrixt(m, n, k, A_val, B_val, C_val, alpha);
A_val += offset_A;
B_val += offset_B;
C_val += offset_C;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Math::compute_tangents(const Array<Real> & normals, Array<Real> & tangents) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = normals.getNbComponent();
UInt tangent_components = spatial_dimension * (spatial_dimension - 1);
AKANTU_DEBUG_ASSERT(tangent_components == tangents.getNbComponent(),
"Cannot compute the tangents, the storage array for tangents"
<< " does not have the good amount of components.");
UInt nb_normals = normals.getSize();
tangents.resize(nb_normals);
Real * normal_it = normals .storage();
Real * tangent_it = tangents.storage();
/// compute first tangent
for (UInt q = 0; q < nb_normals; ++q) {
/// if normal is orthogonal to xy plane, arbitrarly define tangent
if ( Math::are_float_equal(Math::norm2(normal_it), 0) )
tangent_it[0] = 1;
else
Math::normal2(normal_it, tangent_it);
normal_it += spatial_dimension;
tangent_it += tangent_components;
}
/// compute second tangent (3D case)
if (spatial_dimension == 3) {
normal_it = normals .storage();
tangent_it = tangents.storage();
for (UInt q = 0; q < nb_normals; ++q) {
Math::normal3(normal_it, tangent_it, tangent_it + spatial_dimension);
normal_it += spatial_dimension;
tangent_it += tangent_components;
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/common/aka_math.hh b/src/common/aka_math.hh
index 2b73f641a..7ece3baac 100644
--- a/src/common/aka_math.hh
+++ b/src/common/aka_math.hh
@@ -1,301 +1,302 @@
/**
* @file aka_math.hh
*
+ * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
- * @author Peter Spijker <peter.spijker@epfl.ch>
- * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
+ * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
+ * @author Peter Spijker <peter.spijker@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Wed Aug 04 2010
- * @date last modification: Tue Sep 16 2014
+ * @date last modification: Fri May 15 2015
*
* @brief mathematical operations
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_MATH_H__
#define __AKANTU_AKA_MATH_H__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<typename T, bool is_scal>
class Array;
class Math {
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Matrix algebra */
/* ------------------------------------------------------------------------ */
/// @f$ y = A*x @f$
static void matrix_vector(UInt m, UInt n,
const Array<Real, true> & A,
const Array<Real, true> & x,
Array<Real, true> & y, Real alpha = 1.);
/// @f$ y = A*x @f$
static inline void matrix_vector(UInt m, UInt n,
Real * A,
Real * x,
Real * y, Real alpha = 1.);
/// @f$ y = A^t*x @f$
static inline void matrixt_vector(UInt m, UInt n,
Real * A,
Real * x,
Real * y, Real alpha = 1.);
/// @f$ C = A*B @f$
static void matrix_matrix(UInt m, UInt n, UInt k,
const Array<Real, true> & A,
const Array<Real, true> & B,
Array<Real, true> & C, Real alpha = 1.);
/// @f$ C = A*B^t @f$
static void matrix_matrixt(UInt m, UInt n, UInt k,
const Array<Real, true> & A,
const Array<Real, true> & B,
Array<Real, true> & C, Real alpha = 1.);
/// @f$ C = A*B @f$
static inline void matrix_matrix(UInt m, UInt n, UInt k,
Real * A,
Real * B,
Real * C, Real alpha = 1.);
/// @f$ C = A^t*B @f$
static inline void matrixt_matrix(UInt m, UInt n, UInt k,
Real * A,
Real * B,
Real * C, Real alpha = 1.);
/// @f$ C = A*B^t @f$
static inline void matrix_matrixt(UInt m, UInt n, UInt k,
Real * A,
Real * B,
Real * C, Real alpha = 1.);
/// @f$ C = A^t*B^t @f$
static inline void matrixt_matrixt(UInt m, UInt n, UInt k,
Real * A,
Real * B,
Real * C, Real alpha = 1.);
template <bool tr_A, bool tr_B>
static inline void matMul(UInt m, UInt n, UInt k,
Real alpha, Real * A, Real * B,
Real beta, Real * C);
template <bool tr_A>
static inline void matVectMul(UInt m, UInt n,
Real alpha, Real * A, Real * x,
Real beta, Real * y);
static inline void matrix33_eigenvalues(Real * A,
Real * Adiag);
static inline void matrix22_eigenvalues(Real * A,
Real * Adiag);
template<UInt dim>
static inline void eigenvalues(Real * A, Real * d);
/// solve @f$ A x = \Lambda x @f$ and return d and V such as @f$ A V[i:] = d[i] V[i:]@f$
template<typename T>
static void matrixEig(UInt n, T * A, T * d, T * V = NULL);
/// determinent of a 2x2 matrix
static inline Real det2(const Real * mat);
/// determinent of a 3x3 matrix
static inline Real det3(const Real * mat);
/// determinent of a nxn matrix
template<UInt n>
static inline Real det(const Real * mat);
/// determinent of a nxn matrix
template<typename T>
static inline T det(UInt n, const T * mat);
/// inverse a nxn matrix
template<UInt n>
static inline void inv(const Real * mat, Real * inv);
/// inverse a nxn matrix
template<typename T>
static inline void inv(UInt n, const T * mat, T * inv);
/// inverse a 3x3 matrix
static inline void inv3(const Real * mat, Real * inv);
/// inverse a 2x2 matrix
static inline void inv2(const Real * mat, Real * inv);
/// solve A x = b using a LU factorization
template<typename T>
static inline void solve(UInt n, const T * A, T * x, const T * b);
/// return the double dot product between 2 tensors in 2d
static inline Real matrixDoubleDot22(Real * A, Real * B);
/// return the double dot product between 2 tensors in 3d
static inline Real matrixDoubleDot33(Real * A, Real * B);
/// extension of the double dot product to two 2nd order tensor in dimension n
static inline Real matrixDoubleDot(UInt n, Real * A, Real * B);
/* ------------------------------------------------------------------------ */
/* Array algebra */
/* ------------------------------------------------------------------------ */
/// vector cross product
static inline void vectorProduct3(const Real * v1, const Real * v2, Real * res);
/// normalize a vector
static inline void normalize2(Real * v);
/// normalize a vector
static inline void normalize3(Real * v);
/// return norm of a 2-vector
static inline Real norm2(const Real * v);
/// return norm of a 3-vector
static inline Real norm3(const Real * v);
/// return norm of a vector
static inline Real norm(UInt n, const Real * v);
/// return the dot product between 2 vectors in 2d
static inline Real vectorDot2(const Real * v1, const Real * v2);
/// return the dot product between 2 vectors in 3d
static inline Real vectorDot3(const Real * v1, const Real * v2);
/// return the dot product between 2 vectors
static inline Real vectorDot(Real * v1, Real * v2, UInt n);
/* ------------------------------------------------------------------------ */
/* Geometry */
/* ------------------------------------------------------------------------ */
/// compute normal a normal to a vector
static inline void normal2(const Real * v1, Real * res);
/// compute normal a normal to a vector
static inline void normal3(const Real * v1,const Real * v2, Real * res);
/// compute the tangents to an array of normal vectors
static void compute_tangents(const Array<Real> & normals, Array<Real> & tangents);
/// distance in 2D between x and y
static inline Real distance_2d(const Real * x, const Real * y);
/// distance in 3D between x and y
static inline Real distance_3d(const Real * x, const Real * y);
/// radius of the in-circle of a triangle
static inline Real triangle_inradius(const Real * coord1, const Real * coord2, const Real * coord3);
/// radius of the in-circle of a tetrahedron
static inline Real tetrahedron_inradius(const Real * coord1, const Real * coord2, const Real * coord3, const Real * coord4);
/// volume of a tetrahedron
static inline Real tetrahedron_volume(const Real * coord1, const Real * coord2, const Real * coord3, const Real * coord4);
/// compute the barycenter of n points
static inline void barycenter(const Real * coord,
UInt nb_points, UInt spatial_dimension,
Real * barycenter);
/// vector between x and y
static inline void vector_2d(const Real * x, const Real * y, Real * vec);
/// vector pointing from x to y in 3 spatial dimension
static inline void vector_3d(const Real * x, const Real * y, Real * vec);
/// test if two scalar are equal within a given tolerance
static inline bool are_float_equal(Real x, Real y);
/// test if two vectors are equal within a given tolerance
static inline bool are_vector_equal(UInt n, Real * x, Real * y);
#ifdef isnan
# error "You probably included <math.h> which is incompatible with aka_math please use\
<cmath> or add a \"#undef isnan\" before akantu includes"
#endif
/// test if a real is a NaN
static inline bool isnan(Real x);
/// test if the line x and y intersects each other
static inline bool intersects(Real x_min, Real x_max, Real y_min, Real y_max);
/// test if a is in the range [x_min, x_max]
static inline bool is_in_range(Real a, Real x_min, Real x_max);
static inline Real getTolerance() { return tolerance; };
static inline void setTolerance(Real tol) { tolerance = tol; };
template<UInt p, typename T> static inline T pow(T x);
class NewtonRaphson {
public:
NewtonRaphson(Real tolerance, Real max_iteration) :
tolerance(tolerance),
max_iteration(max_iteration) {
}
template<class Functor>
Real solve(const Functor & funct, Real x_0);
private:
Real tolerance;
Real max_iteration;
};
struct NewtonRaphsonFunctor {
NewtonRaphsonFunctor(const std::string & name) : name(name) {}
virtual Real f(Real x) const = 0;
virtual Real f_prime(Real x) const = 0;
std::string name;
};
private:
/// tolerance for functions that need one
static Real tolerance;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "aka_math_tmpl.hh"
__END_AKANTU__
#endif /* __AKANTU_AKA_MATH_H__ */
diff --git a/src/common/aka_math_tmpl.hh b/src/common/aka_math_tmpl.hh
index 7028c1e8e..c27c7e8fb 100644
--- a/src/common/aka_math_tmpl.hh
+++ b/src/common/aka_math_tmpl.hh
@@ -1,776 +1,777 @@
/**
* @file aka_math_tmpl.hh
*
- * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
* @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
- * @author Peter Spijker <peter.spijker@epfl.ch>
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Mathilde Radiguet <mathilde.radiguet@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
+ * @author Peter Spijker <peter.spijker@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Wed Aug 04 2010
- * @date last modification: Tue Sep 16 2014
+ * @date last modification: Wed Oct 21 2015
*
* @brief Implementation of the inline functions of the math toolkit
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
__END_AKANTU__
#include <cmath>
#include <cstring>
#include <typeinfo>
#include "aka_blas_lapack.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline void Math::matrix_vector(UInt im, UInt in,
Real * A,
Real * x,
Real * y, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// y = alpha*op(A)*x + beta*y
char tran_A = 'N';
int incx = 1;
int incy = 1;
double beta = 0.;
int m = im;
int n = in;
aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
#else
memset(y, 0, im*sizeof(Real));
for (UInt i = 0; i < im; ++i) {
for (UInt j = 0; j < in; ++j) {
y[i] += A[i + j*im] * x[j];
}
y[i] *= alpha;
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrixt_vector(UInt im, UInt in,
Real * A,
Real * x,
Real * y, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// y = alpha*op(A)*x + beta*y
char tran_A = 'T';
int incx = 1;
int incy = 1;
double beta = 0.;
int m = im;
int n = in;
aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
#else
memset(y, 0, in*sizeof(Real));
for (UInt i = 0; i < im; ++i) {
for (UInt j = 0; j < in; ++j) {
y[j] += A[j * im + i] * x[i];
}
y[i] *= alpha;
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrix_matrix(UInt im, UInt in, UInt ik,
Real * A,
Real * B,
Real * C, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// C := alpha*op(A)*op(B) + beta*C
char trans_a = 'N';
char trans_b = 'N';
double beta = 0.;
int m = im, n = in, k = ik;
aka_gemm(&trans_a, &trans_b, &m, &n, &k,
&alpha,
A, &m,
B, &k,
&beta,
C, &m);
#else
memset(C, 0, im*in*sizeof(Real));
for (UInt j = 0; j < in; ++j) {
UInt _jb = j * ik;
UInt _jc = j * im;
for (UInt i = 0; i < im; ++i) {
for (UInt l = 0; l < ik; ++l) {
UInt _la = l * im;
C[i + _jc] += A[i + _la] * B[l + _jb];
}
C[i + _jc] *= alpha;
}
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrixt_matrix(UInt im, UInt in, UInt ik,
Real * A,
Real * B,
Real * C, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// C := alpha*op(A)*op(B) + beta*C
char trans_a = 'T';
char trans_b = 'N';
double beta = 0.;
int m = im, n = in, k = ik;
aka_gemm(&trans_a, &trans_b, &m, &n, &k,
&alpha,
A, &k,
B, &k,
&beta,
C, &m);
#else
memset(C, 0, im*in*sizeof(Real));
for (UInt j = 0; j < in; ++j) {
UInt _jc = j*im;
UInt _jb = j*ik;
for (UInt i = 0; i < im; ++i) {
UInt _ia = i*ik;
for (UInt l = 0; l < ik; ++l) {
C[i + _jc] += A[l + _ia] * B[l + _jb];
}
C[i + _jc] *= alpha;
}
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrix_matrixt(UInt im, UInt in, UInt ik,
Real * A,
Real * B,
Real * C, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// C := alpha*op(A)*op(B) + beta*C
char trans_a = 'N';
char trans_b = 'T';
double beta = 0.;
int m = im, n = in, k = ik;
aka_gemm(&trans_a, &trans_b, &m, &n, &k,
&alpha,
A, &m,
B, &n,
&beta,
C, &m);
#else
memset(C, 0, im*in*sizeof(Real));
for (UInt j = 0; j < in; ++j) {
UInt _jc = j * im;
for (UInt i = 0; i < im; ++i) {
for (UInt l = 0; l < ik; ++l) {
UInt _la = l * im;
UInt _lb = l * in;
C[i + _jc] += A[i + _la] * B[j + _lb];
}
C[i + _jc] *= alpha;
}
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrixt_matrixt(UInt im, UInt in, UInt ik,
Real * A,
Real * B,
Real * C, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// C := alpha*op(A)*op(B) + beta*C
char trans_a = 'T';
char trans_b = 'T';
double beta = 0.;
int m = im, n = in, k = ik;
aka_gemm(&trans_a, &trans_b, &m, &n, &k,
&alpha,
A, &k,
B, &n,
&beta,
C, &m);
#else
memset(C, 0, im * in * sizeof(Real));
for (UInt j = 0; j < in; ++j) {
UInt _jc = j*im;
for (UInt i = 0; i < im; ++i) {
UInt _ia = i*ik;
for (UInt l = 0; l < ik; ++l) {
UInt _lb = l * in;
C[i + _jc] += A[l + _ia] * B[j + _lb];
}
C[i + _jc] *= alpha;
}
}
#endif
}
/* -------------------------------------------------------------------------- */
inline Real Math::vectorDot(Real * v1, Real * v2, UInt in) {
#ifdef AKANTU_USE_BLAS
/// d := v1 . v2
int incx = 1, incy = 1, n = in;
Real d = aka_dot(&n, v1, &incx, v2, &incy);
#else
Real d = 0;
for (UInt i = 0; i < in; ++i) {
d += v1[i] * v2[i];
}
#endif
return d;
}
/* -------------------------------------------------------------------------- */
template <bool tr_A, bool tr_B>
inline void Math::matMul(UInt m, UInt n, UInt k,
Real alpha, Real * A, Real * B,
__attribute__ ((unused)) Real beta, Real * C) {
if(tr_A) {
if(tr_B) matrixt_matrixt(m, n, k, A, B, C, alpha);
else matrixt_matrix(m, n, k, A, B, C, alpha);
} else {
if(tr_B) matrix_matrixt(m, n, k, A, B, C, alpha);
else matrix_matrix(m, n, k, A, B, C, alpha);
}
}
/* -------------------------------------------------------------------------- */
template <bool tr_A>
inline void Math::matVectMul(UInt m, UInt n,
Real alpha, Real * A, Real * x,
__attribute__ ((unused)) Real beta, Real * y) {
if(tr_A) {
matrixt_vector(m, n, A, x, y, alpha);
} else {
matrix_vector(m, n, A, x, y, alpha);
}
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Math::matrixEig(UInt n, T * A, T * d, T * V) {
// Matrix A is row major, so the lapack function in fortran will process
// A^t. Asking for the left eigenvectors of A^t will give the transposed right
// eigenvectors of A so in the C++ code the right eigenvectors.
char jobvl;
if(V != NULL)
jobvl = 'V'; // compute left eigenvectors
else
jobvl = 'N'; // compute left eigenvectors
char jobvr('N'); // compute right eigenvectors
T * di = new T[n]; // imaginary part of the eigenvalues
int info;
int N = n;
T wkopt;
int lwork = -1;
// query and allocate the optimal workspace
aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, V, &N, NULL, &N, &wkopt, &lwork, &info);
lwork = int(wkopt);
T * work = new T[lwork];
// solve the eigenproblem
aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, V, &N, NULL, &N, work, &lwork, &info);
AKANTU_DEBUG_ASSERT(info == 0, "Problem computing eigenvalues/vectors. DGEEV exited with the value " << info);
delete [] work;
delete [] di; // I hope for you that there was no complex eigenvalues !!!
}
/* -------------------------------------------------------------------------- */
inline void Math::matrix22_eigenvalues(Real * A, Real *Adiag) {
///d = determinant of Matrix A
Real d = det2(A);
///b = trace of Matrix A
Real b = A[0]+A[3];
Real c = sqrt(b*b - 4 *d);
Adiag[0]= .5*(b + c);
Adiag[1]= .5*(b - c);
}
/* -------------------------------------------------------------------------- */
inline void Math::matrix33_eigenvalues(Real * A, Real *Adiag) {
matrixEig(3, A, Adiag);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void Math::eigenvalues(Real * A, Real * d) {
if(dim == 1) { d[0] = A[0]; }
else if(dim == 2) { matrix22_eigenvalues(A, d); }
// else if(dim == 3) { matrix33_eigenvalues(A, d); }
else matrixEig(dim, A, d);
}
/* -------------------------------------------------------------------------- */
inline Real Math::det2(const Real * mat) {
return mat[0]*mat[3] - mat[1]*mat[2];
}
/* -------------------------------------------------------------------------- */
inline Real Math::det3(const Real * mat) {
return
mat[0]*(mat[4]*mat[8]-mat[7]*mat[5])
- mat[3]*(mat[1]*mat[8]-mat[7]*mat[2])
+ mat[6]*(mat[1]*mat[5]-mat[4]*mat[2]);
}
/* -------------------------------------------------------------------------- */
template<UInt n>
inline Real Math::det(const Real * mat) {
if(n == 1) return *mat;
else if(n == 2) return det2(mat);
else if(n == 3) return det3(mat);
else return det(n, mat);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline T Math::det(UInt n, const T * A) {
int N = n;
int info;
int * ipiv = new int[N+1];
T * LU = new T[N*N];
std::copy(A, A + N*N, LU);
// LU factorization of A
aka_getrf(&N, &N, LU, &N, ipiv, &info);
if(info > 0) {
AKANTU_DEBUG_ERROR("Singular matrix - cannot factorize it (info: "
<< info <<" )");
}
// det(A) = det(L) * det(U) = 1 * det(U) = product_i U_{ii}
T det = 1.;
for (int i = 0; i < N; ++i) det *= (2*(ipiv[i] == i) - 1) * LU[i*n+i];
delete [] ipiv;
delete [] LU;
return det;
}
/* -------------------------------------------------------------------------- */
inline void Math::normal2(const Real * vec,Real * normal) {
normal[0] = vec[1];
normal[1] = -vec[0];
Math::normalize2(normal);
}
/* -------------------------------------------------------------------------- */
inline void Math::normal3(const Real * vec1,const Real * vec2,Real * normal) {
Math::vectorProduct3(vec1,vec2,normal);
Math::normalize3(normal);
}
/* -------------------------------------------------------------------------- */
inline void Math::normalize2(Real * vec) {
Real norm = Math::norm2(vec);
vec[0] /= norm;
vec[1] /= norm;
}
/* -------------------------------------------------------------------------- */
inline void Math::normalize3(Real * vec) {
Real norm = Math::norm3(vec);
vec[0] /= norm;
vec[1] /= norm;
vec[2] /= norm;
}
/* -------------------------------------------------------------------------- */
inline Real Math::norm2(const Real * vec) {
return sqrt(vec[0]*vec[0] + vec[1]*vec[1]);
}
/* -------------------------------------------------------------------------- */
inline Real Math::norm3(const Real * vec) {
return sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
}
/* -------------------------------------------------------------------------- */
inline Real Math::norm(UInt n, const Real * vec) {
Real norm = 0.;
for (UInt i = 0; i < n; ++i) {
norm += vec[i]*vec[i];
}
return sqrt(norm);
}
/* -------------------------------------------------------------------------- */
inline void Math::inv2(const Real * mat,Real * inv) {
Real det_mat = det2(mat);
inv[0] = mat[3] / det_mat;
inv[1] = -mat[1] / det_mat;
inv[2] = -mat[2] / det_mat;
inv[3] = mat[0] / det_mat;
}
/* -------------------------------------------------------------------------- */
inline void Math::inv3(const Real * mat,Real * inv) {
Real det_mat = det3(mat);
inv[0] = (mat[4]*mat[8] - mat[7]*mat[5])/det_mat;
inv[1] = (mat[2]*mat[7] - mat[8]*mat[1])/det_mat;
inv[2] = (mat[1]*mat[5] - mat[4]*mat[2])/det_mat;
inv[3] = (mat[5]*mat[6] - mat[8]*mat[3])/det_mat;
inv[4] = (mat[0]*mat[8] - mat[6]*mat[2])/det_mat;
inv[5] = (mat[2]*mat[3] - mat[5]*mat[0])/det_mat;
inv[6] = (mat[3]*mat[7] - mat[6]*mat[4])/det_mat;
inv[7] = (mat[1]*mat[6] - mat[7]*mat[0])/det_mat;
inv[8] = (mat[0]*mat[4] - mat[3]*mat[1])/det_mat;
}
/* -------------------------------------------------------------------------- */
template<UInt n>
inline void Math::inv(const Real * A, Real * Ainv) {
if(n == 1) *Ainv = 1./ *A;
else if(n == 2) inv2(A, Ainv);
else if(n == 3) inv3(A, Ainv);
else inv(n, A, Ainv);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Math::inv(UInt n, const T * A, T * invA) {
int N = n;
int info;
int * ipiv = new int[N+1];
int lwork = N*N;
T * work = new T[lwork];
std::copy(A, A + n*n, invA);
aka_getrf(&N, &N, invA, &N, ipiv, &info);
if(info > 0) {
AKANTU_DEBUG_ERROR("Singular matrix - cannot factorize it (info: "
<< info <<" )");
}
aka_getri(&N, invA, &N, ipiv, work, &lwork, &info);
if(info != 0) {
AKANTU_DEBUG_ERROR("Cannot invert the matrix (info: "<< info <<" )");
}
delete [] ipiv;
delete [] work;
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Math::solve(UInt n, const T * A, T * x, const T * b) {
int N = n;
int info;
int * ipiv = new int[N];
T * lu_A = new T[N*N];
std::copy(A, A + N*N, lu_A);
aka_getrf(&N, &N, lu_A, &N, ipiv, &info);
if(info > 0) {
AKANTU_DEBUG_ERROR("Singular matrix - cannot factorize it (info: "<< info <<" )");
exit (EXIT_FAILURE);
}
char trans = 'N';
int nrhs = 1;
std::copy(b, b + N, x);
aka_getrs(&trans, &N, &nrhs, lu_A, &N, ipiv, x, &N, &info);
if(info != 0) {
AKANTU_DEBUG_ERROR("Cannot solve the system (info: "<< info <<" )");
exit (EXIT_FAILURE);
}
delete [] ipiv;
delete [] lu_A;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
inline Real Math::matrixDoubleDot22(Real * A, Real * B) {
Real d;
d = A[0] * B[0] + A[1] * B[1]
+ A[2] * B[2] + A[3] * B[3];
return d;
}
/* -------------------------------------------------------------------------- */
inline Real Math::matrixDoubleDot33(Real * A, Real * B) {
Real d;
d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2]
+ A[3] * B[3] + A[4] * B[4] + A[5] * B[5]
+ A[6] * B[6] + A[7] * B[7] + A[8] * B[8];
return d;
}
/* -------------------------------------------------------------------------- */
inline Real Math::matrixDoubleDot(UInt n, Real * A, Real * B) {
Real d = 0.;
for (UInt i = 0; i < n; ++i) {
for (UInt j = 0; j < n; ++j) {
d += A[i*n+j] * B[i*n+j];
}
}
return d;
}
/* -------------------------------------------------------------------------- */
inline void Math::vectorProduct3(const Real * v1, const Real * v2, Real * res) {
res[0] = v1[1]*v2[2] - v1[2]*v2[1];
res[1] = v1[2]*v2[0] - v1[0]*v2[2];
res[2] = v1[0]*v2[1] - v1[1]*v2[0];
}
/* -------------------------------------------------------------------------- */
inline Real Math::vectorDot2(const Real * v1, const Real * v2) {
return (v1[0]*v2[0] + v1[1]*v2[1]);
}
/* -------------------------------------------------------------------------- */
inline Real Math::vectorDot3(const Real * v1, const Real * v2) {
return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]);
}
/* -------------------------------------------------------------------------- */
inline Real Math::distance_2d(const Real * x, const Real * y) {
return sqrt((y[0] - x[0])*(y[0] - x[0]) + (y[1] - x[1])*(y[1] - x[1]));
}
/* -------------------------------------------------------------------------- */
inline Real Math::triangle_inradius(const Real * coord1,
const Real * coord2,
const Real * coord3) {
/**
* @f{eqnarray*}{
* r &=& A / s \\
* A &=& 1/4 * \sqrt{(a + b + c) * (a - b + c) * (a + b - c) (-a + b + c)} \\
* s &=& \frac{a + b + c}{2}
* @f}
*/
Real a, b, c;
a = distance_2d(coord1, coord2);
b = distance_2d(coord2, coord3);
c = distance_2d(coord1, coord3);
Real s;
s = (a + b + c) * 0.5;
return sqrt((s - a) * (s - b) * (s - c) / s);
}
/* -------------------------------------------------------------------------- */
inline Real Math::distance_3d(const Real * x, const Real * y) {
return sqrt((y[0] - x[0])*(y[0] - x[0])
+ (y[1] - x[1])*(y[1] - x[1])
+ (y[2] - x[2])*(y[2] - x[2])
);
}
/* -------------------------------------------------------------------------- */
inline Real Math::tetrahedron_volume(const Real * coord1,
const Real * coord2,
const Real * coord3,
const Real * coord4) {
Real xx[9], vol;
xx[0] = coord2[0]; xx[1] = coord2[1]; xx[2] = coord2[2];
xx[3] = coord3[0]; xx[4] = coord3[1]; xx[5] = coord3[2];
xx[6] = coord4[0]; xx[7] = coord4[1]; xx[8] = coord4[2];
vol = det3(xx);
xx[0] = coord1[0]; xx[1] = coord1[1]; xx[2] = coord1[2];
xx[3] = coord3[0]; xx[4] = coord3[1]; xx[5] = coord3[2];
xx[6] = coord4[0]; xx[7] = coord4[1]; xx[8] = coord4[2];
vol -= det3(xx);
xx[0] = coord1[0]; xx[1] = coord1[1]; xx[2] = coord1[2];
xx[3] = coord2[0]; xx[4] = coord2[1]; xx[5] = coord2[2];
xx[6] = coord4[0]; xx[7] = coord4[1]; xx[8] = coord4[2];
vol += det3(xx);
xx[0] = coord1[0]; xx[1] = coord1[1]; xx[2] = coord1[2];
xx[3] = coord2[0]; xx[4] = coord2[1]; xx[5] = coord2[2];
xx[6] = coord3[0]; xx[7] = coord3[1]; xx[8] = coord3[2];
vol -= det3(xx);
vol /= 6;
return vol;
}
/* -------------------------------------------------------------------------- */
inline Real Math::tetrahedron_inradius(const Real * coord1,
const Real * coord2,
const Real * coord3,
const Real * coord4) {
Real l12, l13, l14, l23, l24, l34;
l12 = distance_3d(coord1, coord2);
l13 = distance_3d(coord1, coord3);
l14 = distance_3d(coord1, coord4);
l23 = distance_3d(coord2, coord3);
l24 = distance_3d(coord2, coord4);
l34 = distance_3d(coord3, coord4);
Real s1, s2, s3, s4;
s1 = (l12 + l23 + l13) * 0.5;
s1 = sqrt(s1*(s1-l12)*(s1-l23)*(s1-l13));
s2 = (l12 + l24 + l14) * 0.5;
s2 = sqrt(s2*(s2-l12)*(s2-l24)*(s2-l14));
s3 = (l23 + l34 + l24) * 0.5;
s3 = sqrt(s3*(s3-l23)*(s3-l34)*(s3-l24));
s4 = (l13 + l34 + l14) * 0.5;
s4 = sqrt(s4*(s4-l13)*(s4-l34)*(s4-l14));
Real volume = Math::tetrahedron_volume(coord1,coord2,coord3,coord4);
return 3*volume/(s1+s2+s3+s4);
}
/* -------------------------------------------------------------------------- */
inline void Math::barycenter(const Real * coord,
UInt nb_points, UInt spatial_dimension,
Real * barycenter) {
memset(barycenter, 0, spatial_dimension * sizeof(Real));
for (UInt n = 0; n < nb_points; ++n) {
UInt offset = n * spatial_dimension;
for (UInt i = 0; i < spatial_dimension; ++i) {
barycenter[i] += coord[offset + i] / (Real) nb_points;
}
}
}
/* -------------------------------------------------------------------------- */
inline void Math::vector_2d(const Real * x, const Real * y, Real * res) {
res[0] = y[0]-x[0];
res[1] = y[1]-x[1];
}
/* -------------------------------------------------------------------------- */
inline void Math::vector_3d(const Real * x, const Real * y, Real * res) {
res[0] = y[0]-x[0];
res[1] = y[1]-x[1];
res[2] = y[2]-x[2];
}
/* -------------------------------------------------------------------------- */
/// Combined absolute and relative tolerance test proposed in
/// Real-time collision detection by C. Ericson (2004)
inline bool Math::are_float_equal(const Real x, const Real y){
Real abs_max = std::max(std::abs(x), std::abs(y));
abs_max = std::max(abs_max, Real(1.));
return std::abs(x - y) <= (tolerance * abs_max);
}
/* -------------------------------------------------------------------------- */
inline bool Math::isnan(Real x) {
#if defined(__INTEL_COMPILER)
#pragma warning ( push )
#pragma warning ( disable : 1572 )
#endif //defined(__INTEL_COMPILER)
// x = x return false means x = quiet_NaN
return !(x == x);
#if defined(__INTEL_COMPILER)
#pragma warning ( pop )
#endif //defined(__INTEL_COMPILER)
}
/* -------------------------------------------------------------------------- */
inline bool Math::are_vector_equal(UInt n, Real * x, Real * y){
bool test = true;
for (UInt i = 0; i < n; ++i) {
test &= are_float_equal(x[i],y[i]);
}
return test;
}
/* -------------------------------------------------------------------------- */
inline bool Math::intersects(Real x_min, Real x_max, Real y_min, Real y_max) {
return ! ((x_max <= y_min) || (x_min >= y_max));
}
/* -------------------------------------------------------------------------- */
inline bool Math::is_in_range(Real a, Real x_min, Real x_max) {
return ((a >= x_min) && (a <= x_max));
}
/* -------------------------------------------------------------------------- */
template<UInt p, typename T> inline T Math::pow(T x) { return (pow<p-1, T>(x)*x); }
template<> inline UInt Math::pow<0, UInt>(__attribute__((unused)) UInt x) { return (1); }
template<> inline Real Math::pow<0, Real>(__attribute__((unused)) Real x) { return (1.); }
/* -------------------------------------------------------------------------- */
template<class Functor>
Real Math::NewtonRaphson::solve(const Functor & funct, Real x_0) {
Real x = x_0;
Real f_x= funct.f(x);
UInt iter = 0;
while(std::abs(f_x) > this->tolerance && iter < this->max_iteration) {
x -= f_x/funct.f_prime(x);
f_x = funct.f(x);
iter++;
}
AKANTU_DEBUG_ASSERT(iter < this->max_iteration, "Newton Raphson (" <<
funct.name <<
") solve did not converge in " << this->max_iteration <<
" iterations (tolerance: " << this->tolerance << ")");
return x;
}
diff --git a/src/common/aka_memory.cc b/src/common/aka_memory.cc
index 81656a406..7db2e7a1b 100644
--- a/src/common/aka_memory.cc
+++ b/src/common/aka_memory.cc
@@ -1,63 +1,64 @@
/**
* @file aka_memory.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Wed Nov 13 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief static memory wrapper
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_memory.hh"
#include "aka_static_memory.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
Memory::Memory(ID id, MemoryID memory_id) : static_memory(StaticMemory::getStaticMemory()),
id(id),
memory_id(memory_id) {
}
/* -------------------------------------------------------------------------- */
Memory::~Memory() {
if(StaticMemory::isInstantiated()) {
std::list<ID>::iterator it;
for (it = handeld_vectors_id.begin(); it != handeld_vectors_id.end(); ++it) {
AKANTU_DEBUG(dblAccessory, "Deleting the vector " << *it);
static_memory.sfree(memory_id, *it);
}
static_memory.destroy();
}
handeld_vectors_id.clear();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/common/aka_memory.hh b/src/common/aka_memory.hh
index cea0ed6cc..811d08467 100644
--- a/src/common/aka_memory.hh
+++ b/src/common/aka_memory.hh
@@ -1,123 +1,124 @@
/**
* @file aka_memory.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Fri Mar 21 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief wrapper for the static_memory, all object which wants
* to access the static_memory as to inherit from the class memory
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MEMORY_HH__
#define __AKANTU_MEMORY_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_static_memory.hh"
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
#include <list>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
protected:
Memory(ID id, MemoryID memory_id = 0);
virtual ~Memory();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
/// malloc
template<class T>
inline Array<T> & alloc(const ID & name,
UInt size,
UInt nb_component);
/// malloc
template<class T>
inline Array<T> & alloc(const ID & name,
UInt size,
UInt nb_component,
const T & init_value);
/* ------------------------------------------------------------------------ */
/// free an array
inline void dealloc(ID name);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
protected:
template<typename T>
inline Array<T> & getArray(const ID & name);
template<typename T>
inline const Array<T> & getArray(const ID & name) const;
public:
AKANTU_GET_MACRO(MemoryID, memory_id, const MemoryID &);
AKANTU_GET_MACRO(ID, id, const ID &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// the static memory instance
StaticMemory & static_memory;
/// list of allocated vectors id
std::list<ID> handeld_vectors_id;
protected:
ID id;
/// the id registred in the static memory
MemoryID memory_id;
};
/* -------------------------------------------------------------------------- */
/* Inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "aka_memory_inline_impl.cc"
#endif
__END_AKANTU__
#endif /* __AKANTU_MEMORY_HH__ */
diff --git a/src/common/aka_memory_inline_impl.cc b/src/common/aka_memory_inline_impl.cc
index a87860076..19dde0512 100644
--- a/src/common/aka_memory_inline_impl.cc
+++ b/src/common/aka_memory_inline_impl.cc
@@ -1,65 +1,66 @@
/**
* @file aka_memory_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
- * @date last modification: Fri Dec 20 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the inline functions of the class Memory
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
template<class T> inline Array<T> & Memory::alloc(const ID & name,
UInt size,
UInt nb_component) {
handeld_vectors_id.push_back(name);
return static_memory.smalloc<T>(memory_id, name,
size, nb_component);
}
/* -------------------------------------------------------------------------- */
template<class T> inline Array<T> & Memory::alloc(const ID & name,
UInt size,
UInt nb_component,
const T & init_value) {
handeld_vectors_id.push_back(name);
return static_memory.smalloc<T>(memory_id, name,
size, nb_component, init_value);
}
/* -------------------------------------------------------------------------- */
inline void Memory::dealloc(ID name) {
AKANTU_DEBUG(dblAccessory, "Deleting the vector " << name);
static_memory.sfree(memory_id, name);
handeld_vectors_id.remove(name);
}
/* -------------------------------------------------------------------------- */
template<class T> inline Array<T> & Memory::getArray(const ID & name) {
return static_cast< Array<T> & >(const_cast<ArrayBase &>(static_memory.getArray(memory_id, name)));
}
/* -------------------------------------------------------------------------- */
template<class T> inline const Array<T> & Memory::getArray(const ID & name) const {
return static_cast< Array<T> & >(const_cast<ArrayBase &>(static_memory.getArray(memory_id, name)));
}
diff --git a/src/common/aka_optimize.cc b/src/common/aka_optimize.cc
index 326fba644..3d73659c5 100644
--- a/src/common/aka_optimize.cc
+++ b/src/common/aka_optimize.cc
@@ -1,81 +1,81 @@
/**
* @file aka_optimize.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue May 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Objects that can be used to carry out optimization
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "aka_common.hh"
#include "aka_optimize.hh"
__BEGIN_AKANTU__
std::ostream& operator<<(std::ostream& os, nlopt::result r) {
switch (r) {
case 1:
os<<"NLOPT_SUCCESS: Generic success return value."<<endl;
break;
case 2:
os<<"NLOPT_STOPVAL_REACHED: Optimization stopped because stopval (above) was reached."<<endl;
break;
case 3:
os<<"NLOPT_FTOL_REACHED: Optimization stopped because ftol_rel or ftol_abs (above) was reached."<<endl;
break;
case 4:
os<<"NLOPT_XTOL_REACHED: Optimization stopped because xtol_rel or xtol_abs (above) was reached."<<endl;
break;
case 5:
os<<"NLOPT_MAXEVAL_REACHED: Optimization stopped because maxeval (above) was reached."<<endl;
break;
case 6:
os<<"NLOPT_MAXTIME_REACHED: Optimization stopped because maxtime (above) was reached."<<endl;
break;
case -1:
os<<"NLOPT_FAILURE: Generic failure code."<<endl;
break;
case -2:
os<<"NLOPT_INVALID_ARGS: Invalid arguments (e.g. lower bounds are bigger than upper bounds, an unknown algorithm was specified, etc.)"<<endl;
break;
case -3:
os<<"NLOPT_OUT_OF_MEMORY: Ran out of memory."<<endl;
break;
case -4:
os<<"NLOPT_ROUNDOFF_LIMITED: Halted because roundoff errors limited progress. (In this case, the optimization still typically returns a useful result."<<endl;
break;
case -5:
os<<"NLOPT_FORCED_STOP: Halted because of a forced termination: the user called nlopt_force_stop(opt) on the optimization’s nlopt_opt object opt from the user’s objective function or constraints."<<endl;
break;
default:
os<<"*** ERROR *** Unrecognized optimization code."<<endl;
exit(1);
}
return os;
}
__END_AKANTU__
diff --git a/src/common/aka_optimize.hh b/src/common/aka_optimize.hh
index 2df512f92..69d0e8ba4 100644
--- a/src/common/aka_optimize.hh
+++ b/src/common/aka_optimize.hh
@@ -1,372 +1,372 @@
/**
* @file aka_optimize.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Objects that can be used to carry out optimization
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_OPTIMIZE_HH__
#define __AKANTU_OPTIMIZE_HH__
#include "aka_config.hh"
#include "aka_common.hh"
#include "aka_point.hh"
#include "solid_mechanics_model.hh"
#include <iostream>
#include <nlopt.hpp>
#include <array/expr.hpp>
//#define DEBUG_OPTIMIZE 1
__BEGIN_AKANTU__
using std::cout;
using std::endl;
typedef array::Array<1,Real> vector_type;
typedef array::Array<2,Real> matrix_type;
std::ostream& operator<<(std::ostream&, nlopt::result);
enum Optimizator_type { Min_t, Max_t };
//! Class used for optimization
/*! This class is a convenience object that inherits from nlopt::opt and carries
* some routines that are common to a nonlinear optimization. The objects sets
* the optimization algorithm as nlopt::LD_SLSQP, a sequential quadratic programming
* (SQP) algorithm for nonlinearly constrained gradient-based optimization
* (supporting both inequality and equality constraints), based on the
* implementation by Dieter Kraft.
*/
class Optimizator : public nlopt::opt {
typedef std::vector<Real> point_type;
typedef nlopt::opt base_type;
point_type& x_; //!< Initial guess for the optimization
Real val_; //!< Function value
public:
//! Parameter constructor that takes an initial guess and a functor
template <class functor_type>
Optimizator(point_type& x0,
functor_type& fn,
Optimizator_type t = Min_t,
nlopt::algorithm alg = nlopt::LD_SLSQP) :
base_type(alg, x0.size()), x_(x0) {
if (t == Min_t)
this->set_min_objective(functor_type::wrap, &fn);
else
this->set_max_objective(functor_type::wrap, &fn);
this->set_xtol_rel(1e-4);
}
//! Carry out the optimization and print result
Real result() {
optimize(x_, val_);
cout<<"Optimum value found at location";
for (size_t i=0; i<x_.size(); ++i)
cout<<" "<<x_[i];
cout<<"\nFunction value: "<<val_;
return val_;
}
};
//! Traits class used as a base class for the Distance_minimizator class template
template <ElementType>
struct Distance_minimizator_traits;
//! Partial template specialization for a segment
template <>
struct Distance_minimizator_traits<_segment_2> {
//! Set lower and upper bounds for the master coordinate
static void set_bounds(nlopt::opt &opt) {
std::vector<Real> lb(1,-1), ub(1,1);
opt.set_lower_bounds(lb);
opt.set_upper_bounds(ub);
}
//! Select the start point between the center or the ends of the segmet
template <class object_type>
static void start(object_type &obj) {
Real min = std::numeric_limits<Real>::infinity();
std::vector<Real> xstart = { -1., 0., 1. }; // check center and extremes of element
int idx = -1;
for (size_t i=0; i<xstart.size(); ++i) {
obj.xi_[0] = xstart[i];
std::vector<Real> grad; // empty vector
Real new_dist = obj(obj.xi_, grad);
if (new_dist < min) {
min = new_dist;
idx = i;
}
}
obj.xi_[0] = xstart[idx];
}
};
//! Constraint function for a triangle
static Real constrain_triangle_3(const std::vector<Real> &xi, std::vector<Real> &grad, void *data) {
if (!grad.empty()) {
grad[0] = 1.;
grad[1] = 1.;
}
return (xi[0] + xi[1] - 1.);
}
//! Helper class used for the definition of triangle partial template specializations
struct Triangle_minimizator_traits {
//! Set lower and upper bounds for the master coordinate
static void set_bounds(nlopt::opt &opt) {
std::vector<Real> lb(2, Real());
opt.set_lower_bounds(lb);
opt.add_inequality_constraint(constrain_triangle_3, NULL, 1e-4);
}
//! Select the start point between the center or the vertices of the triangle
template <class object_type>
static void start(object_type &obj) {
Real min = std::numeric_limits<Real>::infinity();
Real xstart[4][2] = { {0.,0.}, {1.,0.}, {0.,1.}, {1./3.,1./3.} }; // check center and corners of element
int idx = -1;
for (int i=0; i<4; ++i) {
obj.xi_[0] = xstart[i][0];
obj.xi_[1] = xstart[i][1];
std::vector<Real> grad; // empty vector
Real new_dist = obj(obj.xi_, grad);
if (new_dist < min) {
min = new_dist;
idx = i;
}
}
obj.xi_[0] = xstart[idx][0];
obj.xi_[1] = xstart[idx][1];
}
};
//! Partial template specialization for a 3-node triangle
template <>
struct Distance_minimizator_traits<_triangle_3> : public Triangle_minimizator_traits {};
//! Partial template specialization for a 6-node triangle
template <>
struct Distance_minimizator_traits<_triangle_6> : public Triangle_minimizator_traits {};
/*! The Distance_minimizator class template can be used to obtain the closest point
* to a a finite element using the NLopt optimization library.
* \tparam d - The dimension of the problem
* \tparam element_policy - The element type to which the closest point is sought
* The class inherits from Distance_minimizator_traits to take care of functionality
* specific to elements of certain type. The code can be used for elements of type
* _segment_2, _triangle_3, and _triangle_6. The optimization stage is done during the
* constructor by calling the function constructor_common. The closest point is then
* obtained by calling the function point.
*/
template <int d, ElementType element_policy>
class Distance_minimizator : public Distance_minimizator_traits<element_policy> {
friend class Triangle_minimizator_traits;
friend class Distance_minimizator_traits<element_policy>;
const UInt nb_nodes = ElementClass<element_policy>::getNbNodesPerElement();
typedef Distance_minimizator_traits<element_policy> traits_type;
typedef Point<d> point_type;
nlopt::opt opt_; //!< Optimizator reference
std::vector<Real> xi_; //!< Master coordinate closest to point
vector_type p_; //!< Point to which the distance is minimized
matrix_type XX_; //!< Triangle coordinates
UInt counter_; //!< Optimization iteration counter
Real fmin_; //!< Minimum distance value
//! Common function called during construction to carry out the minimization
void constructor_common() {
traits_type::set_bounds(opt_);
opt_.set_min_objective(wrap, this);
opt_.set_ftol_abs(1e-4);
// compute start point
traits_type::start(*this);
// optimize
#ifdef DEBUG_OPTIMIZE
nlopt::result result = opt_.optimize(xi_, fmin_);
if (result > 0)
cout<<"Optimium found in "<<counter_<<" iterations: "<<fmin_<<endl;
cout<<"Point at master coordinate "<<xi_[0]<<": "<<point()<<endl;
cout<<result<<endl;
#else
opt_.optimize(xi_, fmin_);
#endif
}
public:
//! Parameter constructor
/*! This parameter constructor takes the point to which the minimum distance is
* sought, and a container of points points that are the coordinates of the finite
* element
* \param r - Point coordinates
* \param pts - Container of triangle points
*/
template <class point_type, class point_container>
Distance_minimizator(const point_type& p, const point_container& pts)
: opt_(nlopt::LD_SLSQP, d-1), xi_(d-1), p_(d), XX_(nb_nodes,d), counter_() {
// get triangle and point coordinates
for (UInt i=0; i<d; ++i) {
p_[i] = p[i];
for (UInt j=0; j<nb_nodes; ++j)
XX_(j,i) = pts[j][i];
}
// common constructor operation
constructor_common();
}
//! Parameter constructor
/*! This parameter constructor uses a pointer to the coordinates of the point,
* an Element pointer, and the SolidMechanicsModel.
* \param r - Point coordinates
* \param el - Finite element to which the distance is minimized
* \param model - Solid mechanics model
*/
Distance_minimizator(const Real *r, const Element *el, SolidMechanicsModel &model)
: opt_(nlopt::LD_SLSQP, d-1), xi_(d-1), p_(d), XX_(nb_nodes,d), counter_() {
Mesh& mesh = model.getMesh();
const Array<Real> &X = model.getCurrentPosition();
const Array<UInt> &conn = mesh.getConnectivity(el->type);
for (UInt i=0; i<nb_nodes; ++i) {
p_(i) = r[i];
for (UInt j=0; j<d; ++j)
XX_(i,j) = X(conn(el->element,i),j);
}
constructor_common();
}
vector_type operator()(const std::vector<Real> &xi)
{
vector_type N(nb_nodes);
vector_type xi2(xi.size(), const_cast<Real*>(&xi[0]));
ElementClass<element_policy>::computeShapes(xi2, N);
return transpose(XX_)*N;
}
//! Evaluation of the function and its gradient
Real operator()(const std::vector<Real> &xi, std::vector<Real> &grad)
{
// increment function evaluation counter
++counter_;
vector_type x = (*this)(xi);
vector_type diff = x-p_;
if (!grad.empty()) {
// compute shape function derivatives
matrix_type DN(d-1,nb_nodes);
vector_type xi2(xi.size(), const_cast<Real*>(&xi[0]));
ElementClass<element_policy>::computeDNDS(xi2, DN);
DN = transpose(DN);
// compute jacobian
matrix_type J = transpose(XX_)*DN;
// compute function gradient
vector_type gradF = transpose(J) * diff;
for (UInt i=0; i<gradF.size(); ++i)
grad[i] = gradF[i];
}
// return function value
return 0.5 * transpose(diff)*diff;
}
//! Return point at current master coordinate
point_type point() {
vector_type x = (*this)(xi_);
point_type p;
for (UInt i=0; i<x.size(); ++i)
p[i] = x[i];
return p;
}
//! Return the number of function evaluations
UInt iterations() const
{ return counter_; }
//! Return the master coordinate
const std::vector<Real>& master_coordinates()
{ return xi_; }
//! Function that is used to have this class working with nlopt
static double wrap(const std::vector<double> &x, std::vector<double> &grad, void *data) {
return (*reinterpret_cast<Distance_minimizator<d,element_policy>*>(data))(x, grad); }
};
__END_AKANTU__
#endif /* __AKANTU_OPTIMIZE_HH__ */
diff --git a/src/common/aka_plane.hh b/src/common/aka_plane.hh
index 31ac59332..dafac7684 100644
--- a/src/common/aka_plane.hh
+++ b/src/common/aka_plane.hh
@@ -1,81 +1,82 @@
/**
* @file aka_plane.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Tue Jun 17 2014
+ * @date creation: Sun Sep 26 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Geometry class representing planes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_PLANE_HH__
#define __AKANTU_AKA_PLANE_HH__
#include "aka_point.hh"
__BEGIN_AKANTU__
//! Plane class
struct Plane {
typedef Point<3> point_type;
typedef point_type::value_type value_type;
//! Parameter constructor creates a plane out of 3 points
Plane(const point_type& a, const point_type& b, const point_type& c) {
n_ = cross(b - a, c - a).normalize();
d_ = n_*a;
}
//! Return the plane normal
const point_type& normal() const
{ return n_; }
//! Return the disctance to the origin
value_type distance() const
{ return d_; }
//! Standard output stream operator
friend std::ostream& operator<<(std::ostream& os, const Plane& pi) {
os<<"Plane[normal: "<<pi.normal()<<", origin distance: "<<pi.distance()<<"]"<<std::endl;
return os;
}
private:
point_type n_; //!< Plane unit normal
value_type d_; //!< Distance from the plane to the origin
};
__END_AKANTU__
#endif /* __AKANTU_AKA_PLANE_HH__ */
diff --git a/src/common/aka_point.hh b/src/common/aka_point.hh
index 3c7669163..4b779b1ad 100644
--- a/src/common/aka_point.hh
+++ b/src/common/aka_point.hh
@@ -1,270 +1,270 @@
/**
* @file aka_point.hh
*
- * @author David Simon Kammer <david.kammer@epfl.ch>
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue Jun 17 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Geometry class representing points
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_POINT_HH__
#define __AKANTU_AKA_POINT_HH__
#include "aka_common.hh"
#include <cmath>
#include <cassert>
__BEGIN_AKANTU__
const Real inf = std::numeric_limits<Real>::infinity();
//! Point class template
/*! This class represents the abstraction of a point in d-Euclidian
* space.
* \tparam d - Space dimension
* \tparam T - Type for storing coordinate values
*/
template <int d, typename T = Real>
class Point {
public:
typedef T value_type;
//! Return the dimension of the point
constexpr static int dim()
{ return d; }
//! Default constructor creates a point on the origin
Point() {
for (UInt i=0; i<d; ++i)
coord_[i] = value_type();
}
//! Parameter constructor using a const pointer
/*! This constructor can be used to create a point out of a pointer.
* This constructor assumes the memory that contains the coordinates
* is valid.
*/
explicit Point(value_type const* coordinates) {
for (UInt i=0; i<d; ++i)
coord_[i] = coordinates[i];
}
//! Parameter constructor using a pointer
/*! This constructor can be used to create a point out of a pointer.
* This constructor assumes the memory that contains the coordinates
* is valid.
*/
explicit Point(value_type * coordinates) {
for (UInt i=0; i<d; ++i)
coord_[i] = coordinates[i];
}
//! Parameter constructor
/*! This constructor takes exactly d number of parameters so that the
* point can be initialized to the given parameters.
*/
template <typename... Args>
explicit Point(const Args&... args) {
static_assert(sizeof...(Args) <= d , "*** ERROR *** Number of arguments exceeded point dension");
std::fill_n(coord_, d, value_type());
value_type coord[] = { args... };
if (sizeof...(Args) != 0)
for (size_t i=0; i<d; ++i)
coord_[i] = i < sizeof...(Args) ? coord[i] : coord[sizeof...(Args) - 1];
}
//! Less-than operator
/*! This operator enables the use of Point objects in sets and maps
*/
bool operator<(const Point & p) const {
for (int i=0; i<d; ++i)
if (coord_[i] < p[i])
return true;
return false;
}
//! Equal-to operator
bool operator==(const Point & p) const {
for (int i=0; i<d; ++i)
if (coord_[i] != p[i])
return false;
return true;
}
//! Standard output stream operator
friend std::ostream& operator <<(std::ostream &os, const Point &p) {
os<<"{"<<p.coord_[0];
for (int i=1; i<d; ++i)
os<<","<<p.coord_[i];
os<<"}";
return os;
}
public:
//! Get copy of coordinate
value_type operator[] (UInt index) const {
assert(index < d);
return coord_[index];
}
//! Get write access to coordinate
value_type& operator[] (UInt index) {
assert(index < d);
return coord_[index];
}
//! Addition compound assignment operator
Point& operator+=(const Point& p) {
for (int i=0; i<d; ++i)
coord_[i] += p.coord_[i];
return *this;
}
//! Subtraction compound assignment operator
Point& operator-=(const Point& p) {
for (int i=0; i<d; ++i)
coord_[i] -= p.coord_[i];
return *this;
}
//! Scalar multiplication compound assignment operator
template <typename S>
Point& operator*=(S s) {
for (int i=0; i<d; ++i)
coord_[i] *= s;
return *this;
}
//! Scale point so that its magnitude is one
Point& normalize()
{ return (*this)*=(1/std::sqrt(sq_norm())); }
//! Get the square of the magnutud
value_type sq_norm() {
value_type r = value_type();
for (int i=0; i<d; ++i)
r += std::pow(coord_[i],2);
return r;
}
private:
value_type coord_[d]; //! Point coordinates
};
//! Addition between two points
template <int d, typename T>
Point<d,T> operator+(const Point<d,T>& p, const Point<d,T>& q) {
Point<d,T> r(p);
return r += q;
}
//! Subtraction between two points
template <int d, typename T>
Point<d,T> operator-(const Point<d,T>& p, const Point<d,T>& q) {
Point<d,T> r(p);
return r -= q;
}
//! Overload operator* for the scalar product
template <int d, typename T>
typename Point<d,T>::value_type operator*(const Point<d,T>& p, const Point<d,T>& q) {
typename Point<d,T>::value_type r = 0;
for (int i=0; i<d; ++i)
r += p[i] * q[i];
return r;
}
//! Multiply a point by a scalar
template <int d, typename T>
Point<d,T> operator*(const Point<d,T>& p, typename Point<d,T>::value_type s) {
Point<d,T> r(p);
return r *= s;
}
//! Multiply a point by a scalar
template <int d, typename T>
Point<d,T> operator*(typename Point<d,T>::value_type s, const Point<d,T>& p) {
Point<d,T> r(p);
return r *= s;
}
//! Cross product
template <typename T>
Point<3,T> cross(const Point<3,T>& o, const Point<3,T>& p) {
Point<3,T> r;
for (int i=0; i<3; ++i)
r[i] = o[(i+1)%3]*p[(i+2)%3] - o[(i+2)%3]*p[(i+1)%3];
return r;
}
//! Bounding volume class template
/*! This class is used as a building block for constructing
* hierarchies of boundign volumes used in the contact detection
* framework.
*/
template <int d>
struct Bounding_volume {
typedef Point<d> point_type;
typedef typename point_type::value_type value_type;
virtual value_type measure() const = 0;
virtual std::ostream& print(std::ostream& os) const = 0;
Real last_time_;
point_type velocity_;
point_type acceleration_;
//! Standard output stream operator
friend std::ostream& operator<<(std::ostream& os, const Bounding_volume& gv)
{ return gv.print(os); }
};
__END_AKANTU__
#endif /* __AKANTU_AKA_POINT_HH__ */
diff --git a/src/common/aka_polytope.hh b/src/common/aka_polytope.hh
index 35edfbb5e..6e5ae76cf 100644
--- a/src/common/aka_polytope.hh
+++ b/src/common/aka_polytope.hh
@@ -1,132 +1,132 @@
/**
* @file aka_polytope.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue Jun 17 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief k-DOP class template
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_POLYTOPE_HH__
#define __AKANTU_POLYTOPE_HH__
#include "aka_point.hh"
__BEGIN_AKANTU__
//! k-DOP (Discrete Orientation Polytope) class template
/*! \tparam k - Number of planes used to define the polytope
*/
template <int k>
class Polytope {
Real min_[k / 2]; //! Minimum coordinate value along k/2 directions
Real max_[k / 2]; //! Maximum coordinate value along k/2 directions
public:
//! Parameter constructor that uses a container of points
template <class point_container>
Polytope(const point_container& pts) {
Real inf = std::numeric_limits <Real>::infinity();
for (size_t i = 0; i < k / 2; ++i) {
min_[i] = inf;
max_[i] = -inf;
}
initialize(pts);
}
//! Check for collision with another polytope
bool operator& (Polytope & p) {
for (size_t i = 0; i < k / 2; ++i)
if (p.min_[i] > max_[i] || p.max_[i] < min_[i])
return false;
return true;
}
private:
//! Private member function used to initialize the polytope
template <class point_container>
void initialize(const point_container& pts);
};
template <>
template <class point_container>
void Polytope <14>::initialize(const point_container& pts) {
typedef typename point_container::value_type point_type;
Real c = 0.57735026918963;
for (size_t i = 0; i < pts.size(); ++i) {
const point_type& p = pts[i];
// set min/max values along axe (±1,0,0), (0,±1,0), (0,0,±1)
for (size_t j = 0; j < point_type::dim(); ++j) {
min_[j] = std::min(min_[j], p[j]);
max_[j] = std::max(max_[j], p[j]);
}
// set min/max values along axe (1,1,1) and (-1,-1,-1) (normalized)
point_type e1(c, c, c);
Real f1 = p * e1;
min_[3] = std::min(min_[3], f1);
max_[3] = std::max(max_[3], f1);
// set min/max values along axe (1,1,-1) and (-1,-1,1) (normalized)
point_type e2(c, c, -c);
Real f2 = p * e2;
min_[4] = std::min(min_[4], f2);
max_[4] = std::max(max_[4], f2);
// set min/max values along axe (1,-1,1) and (-1,1,-1) (normalized)
point_type e3(c, -c, c);
Real f3 = p * e3;
min_[5] = std::min(min_[5], f3);
max_[5] = std::max(max_[5], f3);
// set min/max values along axe (-1,1,1) and (1,-1,-1) (normalized)
point_type e4(-c, c, c);
Real f4 = p * e4;
min_[6] = std::min(min_[6], f4);
max_[6] = std::max(max_[6], f4);
}
}
__END_AKANTU__
#endif /* __AKANTU_POLYTOPE_HH__ */
diff --git a/src/common/aka_random_generator.hh b/src/common/aka_random_generator.hh
index a05f4ca13..f24b85e4b 100644
--- a/src/common/aka_random_generator.hh
+++ b/src/common/aka_random_generator.hh
@@ -1,351 +1,351 @@
/**
* @file aka_random_generator.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Wed Jun 25 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Wed Nov 11 2015
*
* @brief generic random generator
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
#if defined(AKANTU_USE_CXX11)
# define __CONST_EXPR constexpr
#else
# define __CONST_EXPR
#endif
#ifndef __AKANTU_AKA_RANDOM_GENERATOR_HH__
#define __AKANTU_AKA_RANDOM_GENERATOR_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* List of available distributions */
/* -------------------------------------------------------------------------- */
#define AKANTU_RANDOM_DISTRIBUTION_TYPES \
((uniform, UniformDistribution)) \
((weibull, WeibullDistribution))
#define AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_rdt_, elem)
#define AKANTU_RANDOM_DISTRIBUTION_PREFIX(s, data, elem) \
AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))
enum RandomDistributionType {
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_RANDOM_DISTRIBUTION_PREFIX,
_,
AKANTU_RANDOM_DISTRIBUTION_TYPES)),
_rdt_not_defined
};
/* -------------------------------------------------------------------------- */
/* Distribution */
/* -------------------------------------------------------------------------- */
/// Empty base to be able to store a distribution
template<typename T>
class RandomDistributionBase {
public:
virtual ~RandomDistributionBase() {}
virtual void printself(std::ostream & stream, int indent = 0) const = 0;
};
/* -------------------------------------------------------------------------- */
/* Uniform distribution */
/* -------------------------------------------------------------------------- */
template<typename T>
class UniformDistribution : public RandomDistributionBase<T> {
public:
UniformDistribution(T min = T(0.), T max = T(1.)) : min(min), max(max) { };
/* ------------------------------------------------------------------------ */
template<template<class> class RandomGenerator>
T operator() (RandomGenerator<T> & generator) {
T x = generator() / (RandomGenerator<T>::max() - RandomGenerator<T>::min());
return (x * (max - min) + min);
}
virtual void setParams(std::string value) {
std::stringstream sstr(value);
sstr >> min;
sstr >> max;
}
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << "Uniform [ min=" << min << ", max=" << max << " ]";
};
/* ------------------------------------------------------------------------ */
private:
T min;
T max;
};
/* -------------------------------------------------------------------------- */
/* Weibull distribution */
/* -------------------------------------------------------------------------- */
template<typename T>
class WeibullDistribution : public RandomDistributionBase<T> {
public:
WeibullDistribution(T scale, T shape) : m(shape), lambda(scale) { };
/* ------------------------------------------------------------------------ */
template<template<class> class RandomGenerator>
T operator()(RandomGenerator<T> & generator) {
T x = generator() / (RandomGenerator<T>::max() - RandomGenerator<T>::min());
T e = T(1) / m;
return lambda * std::pow(- std::log(1. - x), e);
}
virtual void setParams(std::string value) {
std::stringstream sstr(value);
sstr >> m;
sstr >> lambda;
}
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << "Weibull [ shape=" << m << ", scale=" << lambda << "]";
}
/* ------------------------------------------------------------------------ */
private:
/// shape parameter or Weibull modulus
T m;
/// scale parameter
T lambda;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Generator */
/* -------------------------------------------------------------------------- */
#if not defined(_WIN32)
template<typename T>
class Rand48Generator {
/* ------------------------------------------------------------------------ */
public:
inline T operator()() { AKANTU_DEBUG_TO_IMPLEMENT(); }
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << "Rand48Generator [seed=" << seed << "]";
}
/* ------------------------------------------------------------------------ */
public:
static void seed(long int s) { _seed = s; srand48(_seed); }
static long int seed() { return _seed; }
static __CONST_EXPR T min() { return 0.; }
static __CONST_EXPR T max() { return 1.; }
/* ------------------------------------------------------------------------ */
private:
static long int _seed;
};
template<>
inline double Rand48Generator<double>::operator()() {
return drand48();
}
#endif
/* -------------------------------------------------------------------------- */
template<typename T>
class RandGenerator {
/* ------------------------------------------------------------------------ */
public:
inline T operator()() { return rand(); }
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << "RandGenerator [seed=" << _seed << "]";
}
/* ------------------------------------------------------------------------ */
public:
static void seed(long int s) { _seed = s; srand(_seed); }
static long int seed() { return _seed; }
static __CONST_EXPR T min() { return 0.; }
static __CONST_EXPR T max() { return RAND_MAX; }
/* ------------------------------------------------------------------------ */
private:
static long int _seed;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#undef AKANTU_RANDOM_DISTRIBUTION_PREFIX
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE(r, data, elem) \
case AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem)): { \
stream << BOOST_PP_STRINGIZE(AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))); \
break; \
}
inline std::ostream & operator <<(std::ostream & stream, RandomDistributionType type) {
switch(type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
default: stream << UInt(type) << " not a RandomDistributionType"; break;
}
return stream;
}
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE
/* -------------------------------------------------------------------------- */
/* Some Helper */
/* -------------------------------------------------------------------------- */
template<typename T, template<typename> class Distribution>
class RandomDistributionTypeHelper {
enum { value = _rdt_not_defined };
};
/* -------------------------------------------------------------------------- */
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE(r, data, elem) \
template<typename T> \
struct RandomDistributionTypeHelper<T, BOOST_PP_TUPLE_ELEM(2, 1, elem)> { \
enum { \
value = AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem)) \
}; \
};
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE
/* -------------------------------------------------------------------------- */
/* RandomParameter */
/* -------------------------------------------------------------------------- */
template<typename T>
class RandomParameter {
public:
RandomParameter(T base_value) :
base_value(base_value), type(_rdt_not_defined), distribution(NULL) { }
template<template <typename> class Distribution>
RandomParameter(T base_value, const Distribution<T> & distribution) :
base_value(base_value),
type((RandomDistributionType)RandomDistributionTypeHelper<T, Distribution>::value),
distribution(new Distribution<T>(distribution)) { }
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_NEW(r, data, elem) \
else if(type == AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))){ \
typedef BOOST_PP_TUPLE_ELEM(2, 1, elem)<T> Dist; \
distribution = new Dist(*static_cast<Dist *>(other.distribution)); \
}
RandomParameter(const RandomParameter & other) :
base_value(other.base_value),
type(other.type) {
if(type == _rdt_not_defined) distribution = NULL;
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_NEW, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
}
inline void setBaseValue(const T & value) { this->base_value = value; }
inline T getBaseValue() const { return this->base_value; }
RandomParameter & operator=(const RandomParameter & other) {
if(this != &other) {
base_value = other.base_value;
type = other.type;
delete distribution;
if(type == _rdt_not_defined) distribution = NULL;
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_NEW, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
}
return *this;
}
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_NEW
/* ------------------------------------------------------------------------ */
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_SET(r, data, elem) \
else if(type == AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))){ \
this->set<BOOST_PP_TUPLE_ELEM(2, 1, elem), Generator>(it, end); \
}
template<template<typename> class Generator, class iterator>
void setValues(iterator it, iterator end) {
if(type == _rdt_not_defined) {
for (; it != end; ++it) *it = this->base_value;
}
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_SET, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
}
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_SET
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << base_value;
if(type != _rdt_not_defined) stream << " " << *distribution;
}
private:
template<template<typename> class Distribution, template<typename> class Generator,
class iterator>
void set(iterator it, iterator end) {
typedef Distribution<T> Dist;
Dist & dist = *(static_cast<Dist *>(this->distribution));
Generator<T> gen;
for (; it != end; ++it) *it = this->base_value + dist(gen);
}
private:
/// Value with no random variations
T base_value;
/// Random distribution type
RandomDistributionType type;
/// Random distribution to use
RandomDistributionBase<T> * distribution;
};
/* -------------------------------------------------------------------------- */
template<typename T>
inline std::ostream & operator <<(std::ostream & stream, RandomDistributionBase<T> & _this) {
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline std::ostream & operator <<(std::ostream & stream, RandomParameter<T> & _this) {
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_AKA_RANDOM_GENERATOR_HH__ */
diff --git a/src/common/aka_safe_enum.hh b/src/common/aka_safe_enum.hh
index 80a4127ef..67cbbdd44 100644
--- a/src/common/aka_safe_enum.hh
+++ b/src/common/aka_safe_enum.hh
@@ -1,81 +1,81 @@
/**
* @file aka_safe_enum.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Safe enums type (see More C++ Idioms/Type Safe Enum on Wikibooks
* http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Safe_Enum)
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_SAFE_ENUM_HH__
#define __AKANTU_AKA_SAFE_ENUM_HH__
__BEGIN_AKANTU__
/// Safe enumerated type
template<typename def, typename inner = typename def::type>
class safe_enum : public def {
typedef typename def::type type;
public:
safe_enum(type v) : val(v) {}
inner underlying() const { return val; }
bool operator == (const safe_enum & s) const { return this->val == s.val; }
bool operator != (const safe_enum & s) const { return this->val != s.val; }
bool operator < (const safe_enum & s) const { return this->val < s.val; }
bool operator <= (const safe_enum & s) const { return this->val <= s.val; }
bool operator > (const safe_enum & s) const { return this->val > s.val; }
bool operator >= (const safe_enum & s) const { return this->val >= s.val; }
operator inner() { return val; };
public:
// Works only if enumerations are contiguous.
class iterator {
public:
iterator(type v) : it(v) { }
void operator++() { ++it; }
safe_enum operator*() { return static_cast<type>(it); }
bool operator!=(iterator const & it) { return it.it != this->it; }
private:
int it;
};
static iterator begin() {
return def::_begin_;
}
static iterator end() {
return def::_end_;
}
protected:
inner val;
};
__END_AKANTU__
#endif /* __AKANTU_AKA_SAFE_ENUM_HH__ */
diff --git a/src/common/aka_static_memory.cc b/src/common/aka_static_memory.cc
index 62231fb45..7a7a48ce5 100644
--- a/src/common/aka_static_memory.cc
+++ b/src/common/aka_static_memory.cc
@@ -1,155 +1,156 @@
/**
* @file aka_static_memory.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Jun 14 2010
- * @date last modification: Fri May 16 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 06 2016
*
* @brief Memory management
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <stdexcept>
#include <sstream>
/* -------------------------------------------------------------------------- */
#include "aka_static_memory.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
bool StaticMemory::is_instantiated = false;
StaticMemory * StaticMemory::single_static_memory = NULL;
UInt StaticMemory::nb_reference = 0;
/* -------------------------------------------------------------------------- */
StaticMemory & StaticMemory::getStaticMemory() {
if(!single_static_memory) {
single_static_memory = new StaticMemory();
is_instantiated = true;
}
nb_reference++;
return *single_static_memory;
}
/* -------------------------------------------------------------------------- */
void StaticMemory::destroy() {
nb_reference--;
if(nb_reference == 0) {
delete single_static_memory;
}
}
/* -------------------------------------------------------------------------- */
StaticMemory::~StaticMemory() {
AKANTU_DEBUG_IN();
MemoryMap::iterator memory_it;
for(memory_it = memories.begin(); memory_it != memories.end(); ++memory_it) {
ArrayMap::iterator vector_it;
for(vector_it = (memory_it->second).begin();
vector_it != (memory_it->second).end();
++vector_it) {
delete vector_it->second;
}
(memory_it->second).clear();
}
memories.clear();
is_instantiated = false;
StaticMemory::single_static_memory = NULL;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StaticMemory::sfree(const MemoryID & memory_id,
const ID & name) {
AKANTU_DEBUG_IN();
try {
ArrayMap & vectors = const_cast<ArrayMap &>(getMemory(memory_id));
ArrayMap::iterator vector_it;
vector_it = vectors.find(name);
if(vector_it != vectors.end()) {
AKANTU_DEBUG_INFO("Array " << name << " removed from the static memory number " << memory_id);
delete vector_it->second;
vectors.erase(vector_it);
AKANTU_DEBUG_OUT();
return;
}
} catch (debug::Exception e) {
AKANTU_EXCEPTION("The memory " << memory_id << " does not exist (perhaps already freed) ["
<< e.what() << "]");
AKANTU_DEBUG_OUT();
return;
}
AKANTU_DEBUG_INFO("The vector " << name << " does not exist (perhaps already freed)");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StaticMemory::printself(std::ostream & stream, int indent) const{
std::string space = "";
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
std::streamsize prec = stream.precision();
stream.precision(2);
stream << space << "StaticMemory [" << std::endl;
UInt nb_memories = memories.size();
stream << space << " + nb memories : " << nb_memories << std::endl;
Real tot_size = 0;
MemoryMap::const_iterator memory_it;
for(memory_it = memories.begin(); memory_it != memories.end(); ++memory_it) {
Real mem_size = 0;
stream << space << AKANTU_INDENT << "Memory [" << std::endl;
UInt mem_id = memory_it->first;
stream << space << AKANTU_INDENT << " + memory id : "
<< mem_id << std::endl;
UInt nb_vectors = (memory_it->second).size();
stream << space << AKANTU_INDENT << " + nb vectors : "
<< nb_vectors << std::endl;
stream.precision(prec);
ArrayMap::const_iterator vector_it;
for(vector_it = (memory_it->second).begin();
vector_it != (memory_it->second).end();
++vector_it) {
(vector_it->second)->printself(stream, indent + 2);
mem_size += (vector_it->second)->getMemorySize();
}
stream << space << AKANTU_INDENT << " + total size : " << printMemorySize<char>(mem_size) << std::endl;
stream << space << AKANTU_INDENT << "]" << std::endl;
tot_size += mem_size;
}
stream << space << " + total size : " << printMemorySize<char>(tot_size) << std::endl;
stream << space << "]" << std::endl;
stream.precision(prec);
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/common/aka_static_memory.hh b/src/common/aka_static_memory.hh
index e2c9a4702..0b6909c86 100644
--- a/src/common/aka_static_memory.hh
+++ b/src/common/aka_static_memory.hh
@@ -1,167 +1,168 @@
/**
* @file aka_static_memory.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Jun 14 2010
- * @date last modification: Fri Mar 21 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Memory management
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* The class handling the memory, allocation/reallocation/desallocation
* The objects can register their array and ask for allocation or realocation
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STATIC_MEMORY_HH__
#define __AKANTU_STATIC_MEMORY_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
typedef std::map<ID, ArrayBase *> ArrayMap;
typedef std::map<MemoryID, ArrayMap> MemoryMap;
/**
* @class StaticMemory
* @brief Class for memory management common to all objects (this class as to
* be accessed by an interface class memory)
*/
class StaticMemory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
private:
/// Default constructor
StaticMemory() {};
public:
virtual ~StaticMemory();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Get the global instance of the StaticMemory
static StaticMemory & getStaticMemory();
static bool isInstantiated() { return is_instantiated; };
/// remove a reference on the static memory
void destroy();
/// access to an Array
inline const ArrayBase & getArray(const MemoryID & memory_id,
const ID & name) const;
/// get all vectors of a memory
inline const ArrayMap & getMemory(const MemoryID & memory_id) const;
/* ------------------------------------------------------------------------ */
/* Class Methods */
/* ------------------------------------------------------------------------ */
public:
/**
* Allocation of an array of type
*
* @param memory_id the id of the memory accessing to the static memory
* @param name name of the array (for example connectivity)
* @param size number of size (for example number of nodes)
* @param nb_component number of component (for example spatial dimension)
* @param type the type code of the array to be allocated
*
* @return pointer to an array of size nb_tupes * nb_component * sizeof(T)
*/
template<typename T>
Array<T> & smalloc(const MemoryID & memory_id, const ID & name,
UInt size, UInt nb_component);
template<typename T>
Array<T> & smalloc(const MemoryID & memory_id,
const ID & name,
UInt size,
UInt nb_component,
const T & init_value);
/**
* free the memory associated to the array name
*
* @param memory_id the id of the memory accessing to the static memory
* @param name the name of an existing array
*/
void sfree(const MemoryID & memory_id, const ID & name);
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// is the static memory instantiated
static bool is_instantiated;
/// unique instance of the StaticMemory
static StaticMemory * single_static_memory;
/// map of all allocated arrays, indexed by their names
MemoryMap memories;
/// number of references on the static memory
static UInt nb_reference;
};
#include "aka_static_memory_tmpl.hh"
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "aka_static_memory_inline_impl.cc"
#endif
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream, const StaticMemory & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_STATIC_MEMORY_HH__ */
diff --git a/src/common/aka_static_memory_inline_impl.cc b/src/common/aka_static_memory_inline_impl.cc
index f90f4ce09..2a10c3a87 100644
--- a/src/common/aka_static_memory_inline_impl.cc
+++ b/src/common/aka_static_memory_inline_impl.cc
@@ -1,63 +1,64 @@
/**
* @file aka_static_memory_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
- * @date last modification: Wed Mar 13 2013
+ * @date last modification: Fri May 22 2015
*
* @brief Implementation of inline functions of the class StaticMemory
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline const ArrayMap & StaticMemory::getMemory(const MemoryID & memory_id) const {
AKANTU_DEBUG_IN();
MemoryMap::const_iterator memory_it;
memory_it = memories.find(memory_id);
if(memory_it == memories.end()) {
AKANTU_SILENT_EXCEPTION("StaticMemory as no memory with ID " << memory_id);
}
AKANTU_DEBUG_OUT();
return memory_it->second;
}
/* -------------------------------------------------------------------------- */
inline const ArrayBase & StaticMemory::getArray(const MemoryID & memory_id,
const ID & name) const {
AKANTU_DEBUG_IN();
const ArrayMap & vectors = getMemory(memory_id);
ArrayMap::const_iterator vectors_it;
vectors_it = vectors.find(name);
if(vectors_it == vectors.end()) {
AKANTU_SILENT_EXCEPTION("StaticMemory as no array named " << name
<< " for the Memory " << memory_id);
}
AKANTU_DEBUG_OUT();
return *(vectors_it->second);
}
/* -------------------------------------------------------------------------- */
diff --git a/src/common/aka_static_memory_tmpl.hh b/src/common/aka_static_memory_tmpl.hh
index fb1da4001..747bfdef8 100644
--- a/src/common/aka_static_memory_tmpl.hh
+++ b/src/common/aka_static_memory_tmpl.hh
@@ -1,86 +1,87 @@
/**
* @file aka_static_memory_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Nov 25 2011
- * @date last modification: Wed Mar 13 2013
+ * @date creation: Thu Jul 15 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief template part of the StaticMemory
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
template<typename T>
Array<T> & StaticMemory::smalloc(const MemoryID & memory_id,
const ID & name,
UInt size,
UInt nb_component) {
AKANTU_DEBUG_IN();
MemoryMap::iterator memory_it;
memory_it = memories.find(memory_id);
if(memory_it == memories.end()){
memories[memory_id] = ArrayMap();
memory_it = memories.find(memory_id);
}
if((memory_it->second).find(name) != (memory_it->second).end()) {
AKANTU_DEBUG_ERROR("The vector \"" << name << "\" is already registred in the memory " << memory_id);
}
Array<T> * tmp_vect = new Array<T>(size, nb_component, name);
(memory_it->second)[name] = tmp_vect;
AKANTU_DEBUG_OUT();
return *tmp_vect;
}
/* -------------------------------------------------------------------------- */
template<typename T>
Array<T> & StaticMemory::smalloc(const MemoryID & memory_id,
const ID & name,
UInt size,
UInt nb_component,
const T & init_value) {
AKANTU_DEBUG_IN();
MemoryMap::iterator memory_it;
memory_it = memories.find(memory_id);
if(memory_it == memories.end()){
memories[memory_id] = ArrayMap();
memory_it = memories.find(memory_id);
}
if((memory_it->second).find(name) != (memory_it->second).end()) {
AKANTU_DEBUG_ERROR("The vector \"" << name << "\" is already registred in the memory " << memory_id);
}
Array<T> * tmp_vect = new Array<T>(size, nb_component, init_value, name);
(memory_it->second)[name] = tmp_vect;
AKANTU_DEBUG_OUT();
return *tmp_vect;
}
/* -------------------------------------------------------------------------- */
diff --git a/src/common/aka_timer.hh b/src/common/aka_timer.hh
index 62f00af39..693aae4cf 100644
--- a/src/common/aka_timer.hh
+++ b/src/common/aka_timer.hh
@@ -1,219 +1,219 @@
/**
* @file aka_timer.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue Jun 17 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief timer object
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TIMER_HH__
#define __AKANTU_TIMER_HH__
#include <cmath>
#include <limits>
#include <ctime>
#include <sys/time.h>
__BEGIN_AKANTU__
// time_t tv_sec; /* seconds since Jan. 1, 1970 */
// suseconds_t tv_usec; /* and microseconds */
// time_t -> long
// suseconds_t -> __int32_t
using std::cout;
using std::endl;
class time {
typedef std::time_t time_t;
time_t microseconds_;
time_t seconds_;
time_t minutes_;
time_t hours_;
time_t days_;
public:
explicit time(const timeval& t)
: microseconds_(t.tv_usec), seconds_(t.tv_sec), minutes_(), hours_(), days_() {
adjust();
}
explicit time(time_t ms = 0, time_t s = 0, time_t min = 0, time_t h = 0, time_t d = 0)
: microseconds_(ms), seconds_(s), minutes_(min), hours_(h), days_(d) {
adjust();
}
time& operator+=(const timeval& t) {
microseconds_ += t.tv_usec;
seconds_ += t.tv_sec;
adjust();
return *this;
}
time& operator+=(const time& t) {
microseconds_ += t.microseconds_;
seconds_ += t.seconds_;
minutes_ += t.minutes_;
hours_ += t.hours_;
days_ += t.days_;
adjust();
return *this;
}
time operator+(const time& t2) {
time t(*this);
t += t2;
return t;
}
friend std::ostream& operator<<(std::ostream& os, const time& t) {
if (t.days_ != 0)
os<<t.days_<<" d, ";
if (t.hours_ != 0)
os<<t.hours_<<" h, ";
if (t.minutes_ != 0)
os<<t.minutes_<<" m, ";
if (t.seconds_ != 0)
os<<t.seconds_<<" s, ";
os<<t.microseconds_<<" µs";
return os;
}
private:
void adjust() {
if (microseconds_ >= 1000000) {
seconds_ += microseconds_ / 1000000;
microseconds_ = microseconds_ % 1000000;
}
if (seconds_ >= 60) {
minutes_ += seconds_ / 60;
seconds_ = seconds_ % 60;
}
if (minutes_ >= 60) {
hours_ += minutes_ / 60;
minutes_ = minutes_ % 60;
}
if (hours_ >= 24) {
days_ += hours_ / 24;
hours_ = hours_ % 24;
}
}
};
///////////////////////////////////////////////////////////////////////////////
// timer classes
template <typename timeval>
void subtract(const timeval& x, timeval y, timeval& r) {
// perform the carry for the later subtraction by updating y
if (x.tv_usec < y.tv_usec) {
int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
y.tv_usec -= 1000000 * nsec;
y.tv_sec += nsec;
}
if (x.tv_usec - y.tv_usec > 1000000) {
int nsec = (x.tv_usec - y.tv_usec) / 1000000;
y.tv_usec += 1000000 * nsec;
y.tv_sec -= nsec;
}
// compute the time remaining to wait
// tv_usec is certainly positive
r.tv_sec = x.tv_sec - y.tv_sec;
r.tv_usec = x.tv_usec - y.tv_usec;
}
class ctimer {
timeval t1_;
public:
ctimer()
{ reset(); }
timeval tac() const {
timeval t2;
gettimeofday(&t2, NULL);
timeval r;
subtract(t2, t1_, r);
return r;
}
inline void reset()
{ gettimeofday(&t1_, NULL); }
friend std::ostream& operator<<(std::ostream& os, const ctimer& t) {
cout<<time(t.tac());
return os;
}
};
class cpu_timer {
std::clock_t t1_;
public:
cpu_timer() : t1_(std::clock()) {}
std::clock_t tac() const {
return std::clock() - t1_;
}
inline void reset() { t1_ = std::clock(); }
inline double seconds()
{ return static_cast<double>(tac())/CLOCKS_PER_SEC; }
friend std::ostream& operator<<(std::ostream& os, const cpu_timer& t) {
os<<t.tac();
return os;
}
};
__END_AKANTU__
#endif /* __AKANTU_TIMER_HH__ */
\ No newline at end of file
diff --git a/src/common/aka_tree.hh b/src/common/aka_tree.hh
index d3cf8fdc5..8e99d2888 100644
--- a/src/common/aka_tree.hh
+++ b/src/common/aka_tree.hh
@@ -1,2318 +1,2318 @@
/**
* @file aka_tree.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue May 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief bounding volume hierarchies
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TREE_HH__
#define __AKANTU_TREE_HH__
#include <cassert>
#include <queue>
#include <set>
#include <iomanip>
//#include <limits>
#include "aka_ball.hh"
#include "aka_bounding_box.hh"
#include "aka_array.hh"
//#define DEBUG_TREE 1
__BEGIN_AKANTU__
using std::cout;
using std::endl;
struct Tree_node_base
{
typedef Tree_node_base* base_ptr;
typedef const Tree_node_base* const_base_ptr;
base_ptr parent_;
base_ptr left_;
base_ptr right_;
static base_ptr _minimum(base_ptr x) {
while (x->left_ != 0) x = x->left_;
return x;
}
static const_base_ptr _minimum(const_base_ptr x) {
while (x->left_ != 0) x = x->left_;
return x;
}
static base_ptr _maximum(base_ptr x) {
while (x->right_ != 0) x = x->right_;
return x;
}
static const_base_ptr _maximum(const_base_ptr x) {
while (x->right_ != 0) x = x->right_;
return x;
}
};
template<typename T>
struct Tree_node : public Tree_node_base
{
typedef T value_tpe;
typedef Tree_node<value_tpe>* link_type;
value_tpe value_;
template<typename... Args>
Tree_node(Args&&... args)
: Tree_node_base(), value_(std::forward<Args>(args)...) { }
};
// iterators
static Tree_node_base* local_leaf_increment(Tree_node_base* x) throw () {
Tree_node_base* y = x->parent_;
if (y->parent_ == x)
return y;
while (x == y->right_) {
x = y;
y = y->parent_;
}
if (y->parent_ == x)
return y;
if (x->right_ != y)
x = y;
if (x->right_ != 0) {
x = x->right_;
while (x->left_ != 0)
x = x->left_;
}
return x;
}
template <class tree_pointer>
tree_pointer* _tree_leaf_increment(tree_pointer* x) throw ()
{ return local_leaf_increment(x); }
template <class tree_pointer>
const tree_pointer* _tree_leaf_increment(const tree_pointer* x) throw ()
{ return local_leaf_increment(const_cast<tree_pointer*>(x)); }
template<typename _Tp>
struct Tree_leaf_iterator
{
typedef _Tp value_type;
typedef _Tp& reference;
typedef _Tp* pointer;
typedef std::bidirectional_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
typedef Tree_leaf_iterator<_Tp> self_type;
typedef Tree_node_base::base_ptr base_ptr;
typedef Tree_node<_Tp>* link_type;
Tree_leaf_iterator() : node_() { }
explicit Tree_leaf_iterator(link_type x) : node_(x) { }
reference operator*() const
{ return static_cast<link_type>(node_)->value_; }
pointer operator->() const
{ return std::__addressof(static_cast<link_type>(node_)->value_); }
self_type& operator++() {
node_ = _tree_leaf_increment(node_);
return *this;
}
self_type operator++(int) {
self_type tmp = *this;
node_ = _tree_leaf_increment(node_);
return tmp;
}
bool operator==(const self_type& x) const
{ return node_ == x.node_; }
bool operator!=(const self_type& x) const
{ return node_ != x.node_; }
bool operator<(const self_type& x) const
{ return node_ < x.node_; }
base_ptr node_;
};
template<typename _Tp>
struct Tree_leaf_const_iterator
{
typedef _Tp value_type;
typedef const _Tp& reference;
typedef const _Tp* pointer;
typedef Tree_leaf_iterator<_Tp> iterator;
typedef std::bidirectional_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
typedef Tree_leaf_const_iterator<_Tp> self_type;
typedef Tree_node_base::const_base_ptr base_ptr;
typedef const Tree_node<_Tp>* link_type;
Tree_leaf_const_iterator() : node_() { }
explicit Tree_leaf_const_iterator(link_type x) : node_(x) { }
Tree_leaf_const_iterator(const iterator& it) : node_(it.node_) { }
iterator _const_cast() const
{ return iterator(static_cast<typename iterator::link_type>(const_cast<typename iterator::base_ptr>(node_))); }
reference operator*() const
{ return static_cast<link_type>(node_)->value_; }
pointer operator->() const
{ return std::__addressof(static_cast<link_type>
(node_)->value_); }
self_type& operator++() {
node_ = _tree_leaf_increment(node_);
return *this;
}
self_type operator++(int) {
self_type tmp = *this;
node_ = _tree_leaf_increment(node_);
return tmp;
}
bool operator==(const self_type& x) const
{ return node_ == x.node_; }
bool operator!=(const self_type& x) const
{ return node_ != x.node_; }
bool operator<(const self_type& x) const
{ return node_ < x.node_; }
base_ptr node_;
};
template<typename _Val>
inline bool operator==(const Tree_leaf_iterator<_Val>& x,
const Tree_leaf_const_iterator<_Val>& y)
{ return x.node_ == y.node_; }
template<typename _Val>
inline bool operator!=(const Tree_leaf_iterator<_Val>& x,
const Tree_leaf_const_iterator<_Val>& y)
{ return x.node_ != y.node_; }
template <class tree_pointer>
static tree_pointer*
local_tree_increment(tree_pointer* x) throw ()
{
if (x->right_ != 0)
{
x = x->right_;
while (x->left_ != 0)
x = x->left_;
}
else
{
tree_pointer* y = x->parent_;
while (x == y->right_)
{
x = y;
y = y->parent_;
}
if (x->right_ != y)
x = y;
}
return x;
}
template <class tree_pointer>
tree_pointer* _tree_increment(tree_pointer* x) throw ()
{ return local_tree_increment(x); }
template <class tree_pointer>
const tree_pointer*
_tree_increment(const tree_pointer* x) throw ()
{ return local_tree_increment(const_cast<tree_pointer*>(x)); }
template <class tree_pointer>
static tree_pointer*
local_tree_decrement(tree_pointer* x) throw () {
if (x->parent_->parent_ == x)
x = x->right_;
else if (x->left_ != 0) {
Tree_node_base* y = x->left_;
while (y->right_ != 0)
y = y->right_;
x = y;
}
else {
tree_pointer* y = x->parent_;
while (x == y->left_) {
x = y;
y = y->parent_;
}
x = y;
}
return x;
}
template <class tree_pointer>
tree_pointer* _tree_decrement(tree_pointer* x) throw ()
{ return local_tree_decrement(x); }
template <class tree_pointer>
const tree_pointer* _tree_decrement(const tree_pointer* x) throw ()
{ return local_tree_decrement(const_cast<tree_pointer*>(x)); }
// iterators
template<typename _Tp>
struct Tree_iterator
{
typedef _Tp value_type;
typedef _Tp& reference;
typedef _Tp* pointer;
typedef std::bidirectional_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
typedef Tree_iterator<_Tp> self_type;
typedef Tree_node_base::base_ptr base_ptr;
typedef Tree_node<_Tp>* link_type;
typedef Tree_leaf_iterator<value_type> leaf_iterator;
Tree_iterator() : node_() { }
explicit Tree_iterator(link_type x) : node_(x) { }
Tree_iterator(const leaf_iterator& it) : node_(it.node_) { }
reference operator*() const
{ return static_cast<link_type>(node_)->value_; }
pointer operator->() const
{ return std::__addressof(static_cast<link_type>(node_)->value_); }
self_type& operator++() {
node_ = _tree_increment(node_);
return *this;
}
self_type operator++(int) {
self_type tmp = *this;
node_ = _tree_increment(node_);
return tmp;
}
self_type& operator--() {
node_ = _tree_decrement(node_);
return *this;
}
self_type operator--(int) {
self_type tmp = *this;
node_ = _tree_decrement(node_);
return tmp;
}
self_type left()
{ return self_type(static_cast<link_type>(node_->left_)); }
self_type right()
{ return self_type(static_cast<link_type>(node_->right_)); }
self_type parent()
{ return self_type(static_cast<link_type>(node_->parent_)); }
bool is_leaf() {
assert(node_ != nullptr);
return node_->left_ == nullptr && node_->right_ == nullptr;
}
bool operator==(const self_type& x) const
{ return node_ == x.node_; }
bool operator!=(const self_type& x) const
{ return node_ != x.node_; }
bool operator<(const self_type& x) const
{ return node_ < x.node_; }
base_ptr node_;
};
template<typename _Tp>
struct Tree_const_iterator
{
typedef _Tp value_type;
typedef const _Tp& reference;
typedef const _Tp* pointer;
typedef Tree_iterator<_Tp> iterator;
typedef std::bidirectional_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
typedef Tree_const_iterator<_Tp> self_type;
typedef Tree_node_base::const_base_ptr base_ptr;
typedef const Tree_node<_Tp>* link_type;
Tree_const_iterator() : node_() { }
explicit Tree_const_iterator(link_type x) : node_(x) { }
Tree_const_iterator(const iterator& it) : node_(it.node_) { }
iterator _const_cast() const
{ return iterator(static_cast<typename iterator::link_type>(const_cast<typename iterator::base_ptr>(node_))); }
reference operator*() const
{ return static_cast<link_type>(node_)->value_; }
pointer operator->() const
{ return std::__addressof(static_cast<link_type>
(node_)->value_); }
self_type& operator++() {
node_ = _tree_increment(node_);
return *this;
}
self_type operator++(int) {
self_type tmp = *this;
node_ = _tree_increment(node_);
return tmp;
}
self_type& operator--() {
node_ = _tree_decrement(node_);
return *this;
}
self_type operator--(int) {
self_type tmp = *this;
node_ = _tree_decrement(node_);
return tmp;
}
self_type left()
{ return self_type(static_cast<link_type>(node_->left_)); }
self_type right()
{ return self_type(static_cast<link_type>(node_->right_)); }
self_type parent()
{ return self_type(static_cast<link_type>(node_->parent_)); }
bool is_leaf() {
assert(node_ != nullptr);
return node_->left_ == nullptr && node_->right_ == nullptr;
}
bool operator==(const self_type& x) const
{ return node_ == x.node_; }
bool operator!=(const self_type& x) const
{ return node_ != x.node_; }
bool operator<(const self_type& x) const
{ return node_ < x.node_; }
base_ptr node_;
};
template<typename _Val>
inline bool operator==(const Tree_iterator<_Val>& x,
const Tree_const_iterator<_Val>& y)
{ return x.node_ == y.node_; }
template<typename _Val>
inline bool operator!=(const Tree_iterator<_Val>& x,
const Tree_const_iterator<_Val>& y)
{ return x.node_ != y.node_; }
// traversal
template <class iterator_type, class functor_type>
void inorder(iterator_type it, functor_type& fn) {
if (it.node_ == nullptr)
return;
inorder(it.left(), fn);
fn(it);
inorder(it.right(), fn);
}
template <class iterator_type, class functor_type>
void preorder(iterator_type it, functor_type& fn) {
if (it.node_ == nullptr)
return;
fn(it);
preorder(it.left(), fn);
preorder(it.right(), fn);
}
template <class iterator_type, class functor_type>
void postorder(iterator_type it, functor_type& fn) {
if (it.node_ == nullptr)
return;
postorder(it.left(), fn);
postorder(it.right(), fn);
fn(it);
}
//! Tree class
template<typename T, template <class> class _Cost, typename _Alloc = std::allocator<T> >
class Tree
{
typedef typename _Alloc::template rebind<Tree_node<T> >::other
_Node_allocator;
protected:
typedef Tree_node_base* base_ptr;
typedef const Tree_node_base* const_base_ptr;
public:
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef Tree_node<T>* link_type;
typedef const Tree_node<T>* const_link_type;
typedef size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef _Cost<value_type> cost_functor;
typedef _Alloc allocator_type;
_Node_allocator& _get_Node_allocator()
{ return *static_cast<_Node_allocator*>(&this->impl_); }
const _Node_allocator& _get_Node_allocator() const
{ return *static_cast<const _Node_allocator*>(&this->impl_); }
allocator_type
get_allocator() const
{ return allocator_type(_get_Node_allocator()); }
private:
link_type _get_node()
{ return impl_._Node_allocator::allocate(1); }
void _put_node(link_type p)
{ impl_._Node_allocator::deallocate(p, 1); }
void _destroy_node(link_type p) {
_get_Node_allocator().destroy(p);
_put_node(p);
}
link_type _clone_node(const_link_type x) {
link_type tmp = _create_node(x->value_);
tmp->left_ = 0;
tmp->right_ = 0;
return tmp;
}
template<typename... _Args>
link_type _create_node(_Args&&... args) {
link_type tmp = _get_node();
try {
_get_Node_allocator().construct(tmp, std::forward<_Args>(args)...);
tmp->left_ = 0;
tmp->right_ = 0;
tmp->parent_ = 0;
}
catch(...) {
_put_node(tmp);
throw;
}
return tmp;
}
private:
template<typename _Cost_functor>
struct Tree_impl : public _Node_allocator
{
_Cost_functor cost_;
Tree_node_base header_;
size_type node_count_; // Keeps track of size of tree.
Tree_impl()
: _Node_allocator(), cost_(), header_(),
node_count_(0)
{ _M_initialize(); }
Tree_impl(const _Cost_functor& comp, const _Node_allocator& a)
: _Node_allocator(a), cost_(comp), header_(),
node_count_(0)
{ _M_initialize(); }
Tree_impl(const _Cost_functor& comp, _Node_allocator&& a)
: _Node_allocator(std::move(a)), cost_(comp),
header_(), node_count_(0)
{ _M_initialize(); }
private:
void
_M_initialize()
{
this->header_.parent_ = 0;
this->header_.left_ = &this->header_;
this->header_.right_ = &this->header_;
}
};
private:
Tree_impl<cost_functor> impl_; //!< Tree implementation instance
base_ptr& _root()
{ return this->impl_.header_.parent_; }
const_base_ptr _root() const
{ return this->impl_.header_.parent_; }
base_ptr& _leftmost()
{ return this->impl_.header_.left_; }
const_base_ptr _leftmost() const
{ return this->impl_.header_.left_; }
base_ptr& _rightmost()
{ return this->impl_.header_.right_; }
const_base_ptr _rightmost() const
{ return this->impl_.header_.right_; }
link_type _begin()
{ return static_cast<link_type>(this->impl_.header_.parent_); }
const_link_type _begin() const
{ return static_cast<const_link_type>(this->impl_.header_.parent_); }
link_type _end()
{ return static_cast<link_type>(&this->impl_.header_); }
const_link_type _end() const
{ return static_cast<const_link_type>(&this->impl_.header_); }
static reference _value(link_type x)
{ return x->value_; }
static const_reference _value(const_link_type x)
{ return x->value_; }
static reference _value(base_ptr x)
{ return static_cast<link_type>(x)->value_; }
static const_reference _value(const_base_ptr x)
{ return static_cast<const_link_type>(x)->value_; }
static link_type _left(base_ptr x)
{ return static_cast<link_type>(x->left_); }
static const_link_type _left(const_base_ptr x)
{ return static_cast<const_link_type>(x->left_); }
static link_type _right(base_ptr x)
{ return static_cast<link_type>(x->right_); }
static const_link_type _right(const_base_ptr x)
{ return static_cast<const_link_type>(x->right_); }
static link_type _parent(base_ptr x)
{ return static_cast<link_type>(x->parent_); }
static const_link_type _parent(const_base_ptr x)
{ return static_cast<const_link_type>(x->parent_); }
void _erase(link_type x) {
while (x != 0)
{
#ifdef DEBUG_TREE
cout<<"pointer x -> "<<x<<endl;
cout<<"calling erase on right -> "<<_right(x)<<endl;
cout<<"destroying node -> "<<_value(x)<<endl;
cout<<"setting x to left -> "<<_left(x)<<endl;
#endif
_erase(_right(x));
link_type y = _left(x);
_destroy_node(x);
--impl_.node_count_; // decrement nodes
x = y;
}
}
link_type _copy(const_link_type x, link_type p) {
link_type top = _clone_node(x);
top->parent_ = p;
try
{
if (x->right_)
top->right_ = _copy(_right(x), top);
p = top;
x = _left(x);
while (x != 0)
{
link_type y = _clone_node(x);
p->left_ = y;
y->parent_ = p;
if (x->right_)
y->right_ = _copy(_right(x), y);
p = y;
x = _left(x);
}
}
catch(...)
{
_erase(top);
throw;
}
return top;
}
void _check_integrity(link_type x) {
while (x != 0) {
link_type r = _right(x);
if (r)
if (r->parent_ != x) {
cout<<"*** ERROR *** Integrity check failed"<<endl;
cout<<"Right child parent mismatch"<<endl;
exit(1);
}
link_type l = _left(x);
if (l)
if (l->parent_ != x) {
cout<<"*** ERROR *** Integrity check failed"<<endl;
cout<<"Left child parent mismatch"<<endl;
exit(1);
}
_check_integrity(r);
x = _left(x);
}
}
public:
typedef Tree_iterator<value_type> iterator;
typedef Tree_const_iterator<value_type> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef Tree_leaf_iterator<value_type> leaf_iterator;
typedef Tree_leaf_const_iterator<value_type> const_leaf_iterator;
// allocation/deallocation
Tree() {}
Tree(const cost_functor& cost, const allocator_type& a = allocator_type())
: impl_(cost, _Node_allocator(a)) { }
Tree(const Tree& x) : impl_(x.impl_.cost_, x._get_Node_allocator())
{
if (x._root() != 0)
{
_root() = _copy(x._begin(), _end());
_leftmost() = Tree_node_base::_minimum(_root());
_rightmost() = Tree_node_base::_maximum(_root());
impl_.node_count_ = x.impl_.node_count_;
}
}
//! construct a tree from link type, defined by the user in any way
Tree(link_type x) {
// integrity check
_check_integrity(x);
if (x) _insert(0,x);
}
~Tree() noexcept
{ _erase(_begin()); }
const cost_functor& cost() const
{ return impl_.cost_; }
void clear() noexcept
{
_erase(_begin());
_leftmost() = _end();
_root() = 0;
_rightmost() = _end();
// assert count == 0, _erase should take care of decrementing the node count
assert(impl_.node_count_ == 0);
// impl_.node_count_ = 0;
}
iterator begin()
{ return iterator(static_cast<link_type>(this->impl_.header_.left_)); }
const_iterator begin() const
{ return const_iterator(static_cast<const_link_type>(this->impl_.header_.left_)); }
iterator end()
{ return iterator(static_cast<link_type>(&this->impl_.header_)); }
const_iterator end() const
{ return const_iterator(static_cast<const_link_type>(&this->impl_.header_)); }
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
const_reverse_iterator rbegin() const
{ return const_reverse_iterator(end()); }
reverse_iterator rend()
{ return reverse_iterator(begin()); }
const_reverse_iterator rend() const
{ return const_reverse_iterator(begin()); }
leaf_iterator leaves_begin()
{ return leaf_iterator(static_cast<link_type>(impl_.header_.left_)); }
const_leaf_iterator leaves_begin() const
{ return const_leaf_iterator(static_cast<const_link_type>(impl_.header_.left_)); }
leaf_iterator leaves_end()
{ return leaf_iterator(static_cast<link_type>(&impl_.header_)); }
const_leaf_iterator leaves_end() const
{ return const_leaf_iterator(static_cast<const_link_type>(&impl_.header_)); }
iterator root()
{ return iterator(static_cast<link_type>(impl_.header_.parent_)); }
const_iterator root() const
{ return const_iterator(static_cast<const_link_type>(impl_.header_.parent_)); }
bool empty() const
{ return impl_.node_count_ == 0; }
size_type size() const
{ return impl_.node_count_; }
size_type max_size() const
{ return _get_Node_allocator().max_size(); }
std::tuple<size_t, size_t, size_t> height() const {
size_t count = 0;
size_t min = std::numeric_limits<size_t>::max();
size_t max = 0;
size_t h = 0;
for (const_leaf_iterator it = leaves_begin(); it != leaves_end(); ++it) {
const_base_ptr x = it.node_;
size_t h1 = 0;
while (x->parent_ != _end()) {
++h1;
x = x->parent_;
}
min = std::min(min, h1);
max = std::max(max, h1);
++count;
h += h1;
}
return std::make_tuple(h/count, min, max);
}
private:
void _add_level(std::queue<link_type>& q, base_ptr x, size_t h, size_t level) {
if (h < level) {
if (x->left_ != 0) _add_level(q, x->left_, h+1, level);
if (x->right_ != 0) _add_level(q, x->right_, h+1, level);
}
else if (h == level)
q.push(static_cast<link_type>(x));
else
return;
}
iterator _insert(base_ptr l, base_ptr r, bool count = true) {
#ifdef DEBUG_TREE
cout<<"inside inserting two for iterators"<<endl;
cout<<"left pointer "<<l<<endl;
if (l)
cout<<"left "<<_value(l)<<endl;
cout<<"right pointer "<<r<<endl;
cout<<"right "<<_value(r)<<endl;
#endif
// set parent to header to count nodes
link_type p = _end();
r->parent_ = p;
// get left most
base_ptr lt = r;
while (lt->left_ != 0)
lt = lt->left_;
#ifdef DEBUG_TREE
cout<<"left most -> "<<_value(lt)<<endl;
#endif
// count nodes
if (count)
for (iterator it(static_cast<link_type>(lt)); it != end(); ++it)
++impl_.node_count_;
// get right most
base_ptr rt = r;
while (rt->right_ != 0)
rt = rt->right_;
// if l is not null, create a new node
link_type lr = static_cast<link_type>(r);
if (l) {
auto vp = impl_.cost_(_value(l),_value(r));
lr = _create_node(vp);
++impl_.node_count_;
p = _parent(l);
lr->parent_ = p;
lr->right_ = r;
lr->left_ = l;
r->parent_ = lr;
l->parent_ = lr;
} else
_leftmost() = lt;
// fix header
if (lr->parent_ == _end()) {
_root() = lr;
_rightmost() = rt;
} else {
// fix parent pointers
if (p->right_ == l)
p->right_ = lr;
else if (p->left_ == l)
p->left_ = lr;
}
// recursively fix parents
auto fix = _value(lr);
while (lr->parent_ != _end()) {
p = _parent(lr);
fix = impl_.cost_(_value(p), fix);
p->value_ = fix;
lr = p;
}
return iterator(static_cast<link_type>(r));
}
bool _is_leaf(const_base_ptr x) const
{ assert(x != nullptr); return (_right(x) == nullptr) && (_left(x) == nullptr); }
public:
struct _Queue_compare {
// pointer - ancestor expansion - best cost tuples
typedef std::tuple<link_type, Real, Real> tuple_type;
bool operator()(const tuple_type& t1, const tuple_type& t2) const
{ return std::get<1>(t1) > std::get<1>(t2); }
};
//! Adapted from Omohundro:89 routine best_sib
template <typename Arg>
iterator best_sibling(Arg&& v) {
#ifdef DEBUG_TREE
cout<<"--------------------"<<endl;
cout<<"inserting "<<v<<endl;
#endif
typedef typename _Queue_compare::tuple_type tuple_type;
typedef typename std::priority_queue<tuple_type, std::vector<tuple_type>, _Queue_compare> queue_type;
// set result to root
link_type result = _begin();
// check for empty tree
if (!result)
return iterator(nullptr);
// check for leaf node
else if (_is_leaf(result))
return iterator(result);
// compute combined cost
Real bcost = impl_.cost_(impl_.cost_(v, _value(result)));
#ifdef DEBUG_TREE
cout<<"root -> "<<_value(result)<<endl;
cout<<"bcost -> "<<bcost<<endl;
#endif
// start the queue
queue_type q;
decltype(impl_.cost_(v)) e, c;
q.push(std::make_tuple(result, 0., bcost));
// while queue is not empty
while (!q.empty()) {
// best candidate
auto t = q.top();
auto nd = std::get<0>(t);
auto aexp = std::get<1>(t);
auto ndvol = std::get<2>(t);
// remove top most element
q.pop();
#ifdef DEBUG_TREE
cout<<" inside while"<<endl;
cout<<" top queue item "<<_value(nd)<<endl;
#endif
// no way to get better than bnd
if (aexp >= bcost) {
#ifdef DEBUG_TREE
cout<<"*** BREAKING"<<endl;
#endif
break;
}
// new ancestor expansion
e = aexp + ndvol - impl_.cost_(_value(nd));
#ifdef DEBUG_TREE
cout<<" a exp "<<e<<endl;
cout<<" bcost "<<bcost<<endl;
cout<<" cost x "<<impl_.cost_(_value(nd))<<endl;
cout<<" e -> "<<e<<endl;
#endif
// do left node
c = impl_.cost_(impl_.cost_(v, _value(nd->left_)));
#ifdef DEBUG_TREE
cout<<" c left -> "<<c<<endl;
#endif
if (c+e <= bcost) {
bcost = c+e;
result = _left(nd);
#ifdef DEBUG_TREE
cout<<" c+e < bcost!!! result set to left "<<_value(result)<<endl;
#endif
}
if(!_is_leaf(nd->left_))
q.push(std::make_tuple(_left(nd), e, c));
// do right node
c = impl_.cost_(impl_.cost_(v, _value(nd->right_)));
#ifdef DEBUG_TREE
cout<<" c right -> "<<c<<endl;
#endif
if (c+e <= bcost) {
bcost = c+e;
result = _right(nd);
#ifdef DEBUG_TREE
cout<<" c+e < bcost!!! result set to right "<<_value(result)<<endl;
#endif
}
if(!_is_leaf(nd->right_))
q.push(std::make_tuple(_right(nd), e, c));
} // while queue is not empty
#ifdef DEBUG_TREE
cout<<"best sibling -> "<<_value(result)<<endl;
#endif
return iterator(result);
}
//! Adapted from Omohundro:89 routine cheap_best_sib
template <typename Arg>
iterator cheap_best_sibling(Arg&& v) {
#ifdef DEBUG_TREE
cout<<"--------------------"<<endl;
cout<<"inserting "<<v<<endl;
#endif
link_type x = _begin();
if (!x)
return iterator(nullptr);
#ifdef DEBUG_TREE
cout<<"root -> "<<_value(x)<<endl;
#endif
link_type result = x;
// compute combined cost
Real wv = impl_.cost_(v, _value(x));
// node vol + ancestor expansion
Real bcost = wv;
// ancestor expansion starts at zero
Real ae = 0;
#ifdef DEBUG_TREE
cout<<"bcost -> "<<bcost<<endl;
#endif
// while not a leaf node
while (x->left_ && x->right_) {
#ifdef DEBUG_TREE
cout<<" inside while"<<endl;
#endif
auto nd = impl_.cost_(_value(x));
// correct for both children
ae += wv - nd;
#ifdef DEBUG_TREE
cout<<" top queue item "<<_value(x)<<endl;
cout<<" a exp "<<ae<<endl;
cout<<" bcost "<<bcost<<endl;
cout<<" cost x "<<nd<<endl;
cout<<" e -> "<<ae<<endl;
#endif
// cannot do any better, insert the volumes in the tree
if (ae >= bcost)
break;
else {
auto lv = impl_.cost_(v, _value(x->left_));
auto rv = impl_.cost_(v, _value(x->right_));
#ifdef DEBUG_TREE
cout<<" c left -> "<<lv<<endl;
#endif
if (ae + lv <= bcost) {
bcost = ae + lv;
result = _left(x);
#ifdef DEBUG_TREE
cout<<" c+e < bcost!!! result set to left "<<_value(_left(x))<<endl;
#endif
}
#ifdef DEBUG_TREE
cout<<" c right -> "<<rv<<endl;
#endif
if (ae + rv <= bcost) {
bcost = ae + rv;
result = _right(x);
#ifdef DEBUG_TREE
cout<<" c+e < bcost!!! result set to right "<<_value(_right(x))<<endl;
#endif
}
// if left branch expands less
if (lv - impl_.cost_(_value(x->left_)) <=
rv - impl_.cost_(_value(x->right_))) {
wv = lv;
x = _left(x);
} else {
wv = rv;
x = _right(x);
}
}
} // while loop
#ifdef DEBUG_TREE
cout<<"best sibling -> "<<_value(result)<<endl;
#endif
return iterator(result);
}
private:
template <class functor_type>
void _execute_at_leaves(iterator x, std::set<base_ptr>& visited, functor_type& fn) {
auto it = visited.find(x.node_);
if (it != visited.end())
return;
visited.insert(x.node_);
if (x.is_leaf())
fn(x);
else {
if (x.node_->left_ != 0) _execute_at_leaves(iterator(static_cast<link_type>(x.node_->left_)), visited, fn);
if (x.node_->right_ != 0) _execute_at_leaves(iterator(static_cast<link_type>(x.node_->right_)), visited, fn);
}
}
public:
//! Collect neighbors
/*! This function is used to collect neighbors from a tree given a functor.
* The functor should implement a parameterless and a one-parameter operator() overloads.
* The first load is used as the predicate to finish the search of neighbors, whereas
* the second one is executed at leaves.
*/
template <class functor_type>
void collect_neighbors(iterator it, functor_type& fn) {
// check for null ptr
if (it.node_ == nullptr)
return;
std::set<base_ptr> visited;
base_ptr p = it.node_;
// execute while predicate is not true
while (!fn()) {
p = p->parent_;
// root node
if (p == _root()->parent_)
break;
_execute_at_leaves(iterator(static_cast<link_type>(p)), visited, fn);
}
}
template <typename Arg>
std::pair<iterator,bool> cheap_insert(Arg&& v) {
iterator it = cheap_best_sibling(v);
link_type r = _create_node(v);
return std::pair<iterator, bool>(_insert(it.node_, r), true);
}
template <typename Arg>
std::pair<iterator,bool> insert(Arg&& v) {
iterator it = best_sibling(v);
link_type r = _create_node(v);
return std::pair<iterator, bool>(_insert(it.node_, r), true);
}
std::pair<iterator,bool> insert(link_type x)
{ return insert(iterator(x)); }
std::pair<iterator,bool> insert(iterator vit) {
iterator it = best_sibling(_value(vit.node_));
return std::pair<iterator, bool>(_insert(it.node_, vit.node_), true);
}
iterator sibling(iterator it) {
base_ptr x = it.node_;
if (!x)
return iterator(nullptr);
if (x == _root())
return end();
base_ptr p = x->parent_;
assert (p != 0);
if (p->left_ == x)
return iterator(_right(p));
return iterator(_left(p));
}
public:
iterator relocate_parent(iterator it) {
#if DEBUG_TREE
if (it.node_)
cout<<"relocating node "<<_value(it.node_)<<endl;
#endif
link_type x = static_cast<link_type>(it.node_);
// null pointer
if (!x)
return end();
// get parent
link_type p = _parent(x);
// if parent is header return root
if (p == _end())
return iterator(_begin());
// get grand-parent
link_type gp = _parent(p);
// no need to recompute volume as the parent has
// the enclosing volume of its children
// sibling
link_type s = x == p->left_ ? _right(p) : _left(p);
#ifdef DEBUG_TREE
cout<<"relocating x -> "<<_value(x)<<endl;
cout<<"parent of node -> "<<_value(p)<<endl;
cout<<"sibling -> "<<_value(s)<<endl;
#endif
if (gp == _end()) {
#ifdef DEBUG_TREE
cout<<"*** WARNING *** sibling new parent is the header!"<<endl;
#endif
_root() = s;
} else if (gp->left_ == p) {
gp->left_ = s;
#ifdef DEBUG_TREE
cout<<"setting parent->parent->left to sibling"<<endl;
#endif
}
else if (gp->right_ == p) {
gp->right_ = s;
#ifdef DEBUG_TREE
cout<<"setting parent->parent->right to sibling"<<endl;
#endif
} else
assert(false);
// set parent of sibling
s->parent_ = p->parent_;
// recursively fix parents
link_type r = _parent(s);
while (r != _end()) {
r->value_ = impl_.cost_(_value(r->right_), _value(r->left_));
r = _parent(r);
}
// destroy parent node p and reinsert x into the tree
x->parent_ = 0;
p->parent_ = 0;
p->left_ = 0;
p->right_ = 0;
_erase(p);
// get the best sibling
iterator bit = best_sibling(_value(x));
#ifdef DEBUG_TREE
cout<<"best sibling for relocation -> "<<bit.node_<<endl;
if (it.node_)
cout<<" best sibling value -> "<<_value(bit.node_)<<endl;
#endif
iterator result = _insert(bit.node_, x, false);
// set leftmost and rightmost
base_ptr lt = _root();
while (lt->left_ != 0)
lt = lt->left_;
_leftmost() = lt;
base_ptr rt = _root();
while (rt->right_ != 0)
rt = rt->right_;
_rightmost() = rt;
return result;
}
iterator erase(iterator it) {
link_type x = static_cast<link_type>(it.node_);
// null pointer
if (!x)
return end();
// root node
else if (x == _root()) {
clear();
return end();
}
link_type p = _parent(x);
link_type s; // sibling
if (x == p->left_) {
s = _right(p);
p->right_ = 0; // set to zero to use erase
} else {
s = _left(p);
p->left_ = 0;
}
#ifdef DEBUG_TREE
cout<<"erasing x -> "<<_value(x)<<endl;
cout<<"parent of node -> "<<_value(p)<<endl;
cout<<"sibling -> "<<_value(s)<<endl;
#endif
if (_leftmost() == x) {
base_ptr l = s;
while (l->left_ != 0)
l = l->left_;
_leftmost() = l;
#ifdef DEBUG_TREE
cout<<"x is leftmost, so setting leftmost to "<<_value(l)<<endl;
#endif
} if (_rightmost() == x) {
base_ptr r = s;
while (r->right_ != 0)
r = r->right_;
_rightmost() = r;
#ifdef DEBUG_TREE
cout<<"x is rightmost, so setting rightmost to "<<_value(r)<<endl;
#endif
}
s->parent_ = p->parent_;
if (p->parent_ == _end()) {
#ifdef DEBUG_TREE
cout<<"*** WARNING *** sibling new parent is the header!"<<endl;
#endif
_root() = s;
} else if (p->parent_->left_ == p) {
p->parent_->left_ = s;
#ifdef DEBUG_TREE
cout<<"setting parent->parent->left to sibling"<<endl;
#endif
}
else {
p->parent_->right_ = s;
#ifdef DEBUG_TREE
cout<<"setting parent->parent->right to sibling"<<endl;
#endif
}
#ifdef DEBUG_TREE
cout<<"p right -> "<<p->right_<<endl;
cout<<"p left -> "<<p->left_<<endl;
if (p->right_)
cout<<"p right value -> "<<_value(p->right_)<<endl;
if (p->left_)
cout<<"p left value -> "<<_value(p->left_)<<endl;
#endif
// recursively fix parents
link_type r = _parent(s);
while (r != _end()) {
r->value_ = _value(r->right_) + _value(r->left_);
r = _parent(r);
}
// erase subtree rooted at p
_erase(p);
return iterator(s);
}
Real volume() const {
Real v = 0;
for (const_iterator it = begin(); it != end(); ++it)
v += it->measure();
return v;
}
friend std::ostream& operator<<(std::ostream& os, const Tree& t) {
os<<"Tree: count "<<t.impl_.node_count_<<endl;
os<<" header: "<<&t.impl_.header_<<endl;
if (t.impl_.header_.parent_)
os<<" ROOT: "<<t.impl_.header_.parent_<<", value "<<_value(t.impl_.header_.parent_)<<endl;
os<<" left: "<<t.impl_.header_.left_<<endl;
os<<" right: "<<t.impl_.header_.right_<<endl;
size_t c = 0;
Real v = 0;
os<<endl;
for (Tree::const_iterator it = t.begin(); it != t.end(); ++it, ++c) {
Real cost = t.impl_.cost_(*it);
if (it.node_ == t.impl_.header_.parent_) {
os<<" ROOT "<<it.node_;
if (it.node_ == t._leftmost())
os<<" [LEFTMOST]";
if (it.node_ == t._rightmost())
os<<" [RIGHTMOST]";
os<<"\n value: "<<*it<<endl;
os<<" parent: "<<it.node_->parent_<<endl;
} else {
os<<" pointer "<<it.node_;
if (it.node_ == t._leftmost())
os<<" [LEFTMOST]";
if (it.node_ == t._rightmost())
os<<" [RIGHTMOST]";
os<<"\n value: "<<*it<<endl;
os<<" parent: "<<it.node_->parent_<<", value "<<_value(it.node_->parent_)<<endl;
}
if (it.node_->left_)
os<<" left: "<<it.node_->left_<<", value "<<_value(it.node_->left_)<<endl;
if (it.node_->right_)
os<<" right: "<<it.node_->right_<<", value "<<_value(it.node_->right_)<<endl;
if (!it.node_->left_ && !it.node_->right_)
os<<" leaf"<<endl;
os<<" cost: "<<cost<<endl;
os<<endl;
v += cost;
}
cout<<"total cost -> "<<v<<endl;
if (c != t.impl_.node_count_)
cout<<"*** WARNING *** Tree node count mismatch "<<t.impl_.node_count_<<" != "<<c<<endl;
return os;
}
template <class functor_type>
functor_type execute_at_level(size_t level, functor_type fn) {
link_type x = _begin();
if (x == nullptr)
return fn;
std::queue<link_type> q;
_add_level(q, x, 0, level);
while (!q.empty()) {
link_type l = q.front();
assert(l != 0);
fn(iterator(l));
q.pop();
}
return fn;
}
};
template <class object_type>
struct Cost_functor {
auto operator()(const object_type& o) const -> decltype(o.measure())
{ return o.measure(); }
auto operator()(const object_type& o1, const object_type& o2) const -> decltype(o1+o2)
{ return (o1+o2); }
};
template <class link_type>
struct Tuple_compare {
typedef std::tuple<link_type, link_type, Real> tuple_type;
bool operator()(const tuple_type& t1, const tuple_type& t2) const
{ return std::get<2>(t1) > std::get<2>(t2); }
};
// bottom up tree construction
template <class tree_type, class volume_container>
tree_type* construct_tree_bottom_up(const volume_container& volumes)
{
// online tree type definitions
typedef typename tree_type::value_type volume_type;
typedef typename tree_type::cost_functor cost_functor;
typedef typename tree_type::iterator iterator_type;
// queue type definitions
typedef std::tuple<iterator_type, iterator_type, Real> tuple_type;
typedef typename std::priority_queue<tuple_type, std::vector<tuple_type>, Tuple_compare<iterator_type> > queue_type;
// already paired container type definitions
typedef std::set<iterator_type> paired_set;
typedef typename paired_set::iterator paired_iterator;
size_t numVolumes = volumes.size();
assert(numVolumes != 0);
tree_type* tp = new tree_type();
const cost_functor& cost = tp->cost();
tree_type& t = *tp;
queue_type q;
paired_set s;
std::vector<iterator_type> links(numVolumes);
// insert volumes into online tree
for (size_t i=0; i<numVolumes; ++i) {
std::pair<iterator_type, bool> p = t.insert(volumes[i]);
assert(p.second);
links[i] = p.first;
}
iterator_type ii,jj;
for (size_t i=0; i<numVolumes-1; ++i) {
Real merged = std::numeric_limits<Real>::infinity();
for (size_t j=i+1; j<numVolumes; ++j) {
volume_type v = cost(*links[i], *links[j]);
Real measure = cost(v);
if (measure < merged) {
ii = links[i];
jj = links[j];
merged = measure;
}
}
q.push(std::make_tuple(ii,jj,merged));
}
while (!q.empty()) {
// best candidate
auto tuple = q.top();
iterator_type node = std::get<0>(tuple);
iterator_type pair = std::get<1>(tuple);
q.pop();
paired_iterator it = s.find(node);
if (it != s.end())
continue;
it = s.find(pair);
if (it != s.end())
continue;
#if DEBUG_TREE
cout<<t<<endl;
cout<<"node -> "<<node.node_<<endl;
cout<<"node value -> "<<*node<<endl;
cout<<"pair -> "<<pair.node_<<endl;
cout<<"pair value -> "<<*pair<<endl;
cout<<"volume -> "<<std::get<2>(tuple)<<endl;
#endif
// obtain best pair from online tree
iterator_type best = t.sibling(node);
#if DEBUG_TREE
cout<<"best sibling -> "<<*best<<endl;
#endif
if (pair == best) {
iterator_type parent = t.relocate_parent(node);
assert(parent != t.end());
#if DEBUG_TREE
cout<<"BEST SIBLING MATCHES! relocating..."<<endl;
cout<<" parent -> "<<*parent<<endl;
#endif
// add paired nodes to container
s.insert(node);
s.insert(pair);
// compute best pair for the parent
best = t.sibling(parent);
if (best != t.end()) {
tuple_type tuple = std::make_tuple(parent, best, cost(cost(*parent, *best)));
q.push(tuple);
iterator_type node = std::get<0>(tuple);
iterator_type pair = std::get<1>(tuple);
#if DEBUG_TREE
cout<<" pushing new tuple "<<endl;
cout<<" node -> "<<*node<<endl;
cout<<" pair -> "<<*pair<<endl;
cout<<" volume -> "<<std::get<2>(tuple)<<endl;
#endif
}
}
// else enqueue new pair
else {
if (best != t.end()) {
tuple_type tuple = std::make_tuple(node,best, cost(cost(*node, *best)));
q.push(tuple);
iterator_type node = std::get<0>(tuple);
iterator_type pair = std::get<1>(tuple);
#if DEBUG_TREE
cout<<"BEST SIBLING DOES NOT MATCH!"<<endl;
cout<<" pushing new tuple "<<endl;
cout<<" node -> "<<*node<<endl;
cout<<" pair -> "<<*pair<<endl;
cout<<" volume -> "<<std::get<2>(tuple)<<endl;
#endif
}
}
}
return tp;
}
template <class volume_type>
class Volume_creator;
template<int d>
struct Volume_creator<Ball<d> > {
typedef typename Ball<d>::point_type point_type;
template <class coord_array>
static Ball<d> create(const coord_array& coord) {
std::vector<point_type> pts;
size_t nnodes = coord.size();
pts.reserve(nnodes);
for (size_t i=0; i<nnodes; ++i)
pts.push_back(point_type(coord[i]));
return bounding_ball<d>(pts);
}
};
template <int d>
struct Volume_creator<BoundingBox<d> > {
typedef typename BoundingBox<d>::point_type point_type;
template <class coord_array>
static Sphere create(const coord_array& coord) {
std::vector<point_type> pts;
size_t nnodes = coord.size();
pts.reserve(nnodes);
for (size_t i=0; i<nnodes; ++i)
pts.push_back(point_type(coord[i]));
return BoundingBox<d>(pts.begin(), pts.end());
}
};
// bottom up tree construction
template <class tree_type, class model_type, class element_type>
tree_type* construct_tree_bottom_up(model_type& model) {
// online tree type definitions
typedef typename tree_type::value_type volume_type;
typedef typename tree_type::cost_functor cost_functor;
typedef typename tree_type::iterator iterator_type;
// queue type definitions
typedef std::tuple<iterator_type, iterator_type, Real> tuple_type;
typedef typename std::priority_queue<tuple_type, std::vector<tuple_type>, Tuple_compare<iterator_type> > queue_type;
// already paired container type definitions
typedef std::set<iterator_type> paired_set;
typedef typename paired_set::iterator paired_iterator;
tree_type* tp = new tree_type();
tree_type& t = *tp;
const cost_functor& cost = t.cost();
std::vector<iterator_type> links;
typedef typename model_type::mesh_type mesh_type;
mesh_type& mesh = model.getMesh();
int dim = mesh.getSpatialDimension();
// iterate over elements of lower dimension
typename mesh_type::type_iterator it = mesh.firstType(dim-1);
typename mesh_type::type_iterator end = mesh.lastType(dim-1);
size_t numVolumes = 0;
for(; it != end; ++it) {
// add elements to corresponding surface
for(UInt e = 0; e < mesh.getNbElement(*it); ++e) {
// create solid mechanics element
element_type el(model, *it, e);
// vector of coordinates for update
std::vector<const Real*> coord = el.coordinates();
// create leaf volume
volume_type v = Volume_creator<volume_type>::create(coord);
// do not add zero measure volumes
if (v.measure() == 0 && dim != 1)
continue;
std::pair<iterator_type, bool> p = t.insert(v);
assert(p.second);
links.push_back(p.first);
++numVolumes;
// save leaf data
if (!t.add_data(p.first,el)) {
cout<<"*** ERROR *** Could not add data. Aborting..."<<endl;
exit(1);
}
} // loop over elements
} // loop over types of element
if (numVolumes == 0) {
cout<<"*** ERROR *** No volumes were created. Aborting..."<<endl;
exit(1);
}
queue_type q;
paired_set s;
iterator_type ii,jj;
for (size_t i=0; i<numVolumes-1; ++i) {
Real merged = std::numeric_limits<Real>::infinity();
for (size_t j=i+1; j<numVolumes; ++j) {
volume_type v = cost(*links[i], *links[j]);
Real measure = v.measure();
if (measure < merged) {
ii = links[i];
jj = links[j];
merged = measure;
}
}
q.push(std::make_tuple(ii,jj,merged));
}
while (!q.empty()) {
// best candidate
auto tuple = q.top();
iterator_type node = std::get<0>(tuple);
iterator_type pair = std::get<1>(tuple);
q.pop();
paired_iterator it = s.find(node);
if (it != s.end())
continue;
it = s.find(pair);
if (it != s.end())
continue;
#if DEBUG_TREE
cout<<t<<endl;
cout<<"node -> "<<node.node_<<endl;
cout<<"node value -> "<<*node<<endl;
cout<<"pair -> "<<pair.node_<<endl;
cout<<"pair value -> "<<*pair<<endl;
cout<<"volume -> "<<std::get<2>(tuple)<<endl;
#endif
// obtain best pair from online tree
iterator_type best = t.sibling(node);
#if DEBUG_TREE
cout<<"best sibling -> "<<*best<<endl;
#endif
if (pair == best) {
iterator_type parent = t.relocate_parent(node);
assert(parent != t.end());
#if DEBUG_TREE
cout<<"BEST SIBLING MATCHES! relocating..."<<endl;
cout<<" parent -> "<<*parent<<endl;
#endif
// add paired nodes to container
s.insert(node);
s.insert(pair);
// compute best pair for the parent
best = t.sibling(parent);
if (best != t.end()) {
tuple_type tuple = std::make_tuple(parent, best, cost(cost(*parent,*best)));
q.push(tuple);
iterator_type node = std::get<0>(tuple);
iterator_type pair = std::get<1>(tuple);
#if DEBUG_TREE
cout<<" pushing new tuple "<<endl;
cout<<" node -> "<<*node<<endl;
cout<<" pair -> "<<*pair<<endl;
cout<<" volume -> "<<std::get<2>(tuple)<<endl;
#endif
}
}
// else enqueue new pair
else {
if (best != t.end()) {
tuple_type tuple = std::make_tuple(node,best, cost(cost(*node, *best)));
q.push(tuple);
iterator_type node = std::get<0>(tuple);
iterator_type pair = std::get<1>(tuple);
#if DEBUG_TREE
cout<<"BEST SIBLING DOES NOT MATCH!"<<endl;
cout<<" pushing new tuple "<<endl;
cout<<" node -> "<<*node<<endl;
cout<<" pair -> "<<*pair<<endl;
cout<<" volume -> "<<std::get<2>(tuple)<<endl;
#endif
}
}
}
return tp;
}
// bottom up tree construction
template <class tree_type, class element_container>
tree_type* construct_tree_bottom_up(element_container& elems) {
// element type
typedef typename element_container::value_type element_type;
// online tree type definitions
typedef typename tree_type::value_type volume_type;
typedef typename tree_type::cost_functor cost_functor;
typedef typename tree_type::iterator iterator_type;
// queue type definitions
typedef std::tuple<iterator_type, iterator_type, Real> tuple_type;
typedef typename std::priority_queue<tuple_type, std::vector<tuple_type>, Tuple_compare<iterator_type> > queue_type;
// already paired container type definitions
typedef std::set<iterator_type> paired_set;
typedef typename paired_set::iterator paired_iterator;
tree_type* tp = new tree_type();
tree_type& t = *tp;
const cost_functor& cost = t.cost();
std::vector<iterator_type> links;
size_t numVolumes = 0;
for (typename element_container::iterator it = elems.begin();
it != elems.end(); ++it) {
element_type &el = *it;
// vector of coordinates for update
std::vector<const Real*> coord = el.coordinates();
// create leaf volume
volume_type v = Volume_creator<volume_type>::create(coord);
// do not add zero measure volumes
if (v.measure() == 0)
continue;
std::pair<iterator_type, bool> p = t.insert(v);
assert(p.second);
links.push_back(p.first);
++numVolumes;
// save leaf data
if (!t.add_data(p.first,el)) {
cout<<"*** ERROR *** Could not add data. Aborting..."<<endl;
exit(1);
}
} // loop over elements in container
if (numVolumes == 0) {
cout<<"*** ERROR *** No volumes were created. Aborting..."<<endl;
exit(1);
}
queue_type q;
paired_set s;
iterator_type ii,jj;
for (size_t i=0; i<numVolumes-1; ++i) {
Real merged = std::numeric_limits<Real>::infinity();
for (size_t j=i+1; j<numVolumes; ++j) {
volume_type v = cost(*links[i], *links[j]);
Real measure = v.measure();
if (measure < merged) {
ii = links[i];
jj = links[j];
merged = measure;
}
}
q.push(std::make_tuple(ii,jj,merged));
}
while (!q.empty()) {
// best candidate
auto tuple = q.top();
iterator_type node = std::get<0>(tuple);
iterator_type pair = std::get<1>(tuple);
q.pop();
paired_iterator it = s.find(node);
if (it != s.end())
continue;
it = s.find(pair);
if (it != s.end())
continue;
#if DEBUG_TREE
cout<<t<<endl;
cout<<"node -> "<<node.node_<<endl;
cout<<"node value -> "<<*node<<endl;
cout<<"pair -> "<<pair.node_<<endl;
cout<<"pair value -> "<<*pair<<endl;
cout<<"volume -> "<<std::get<2>(tuple)<<endl;
#endif
// obtain best pair from online tree
iterator_type best = t.sibling(node);
#if DEBUG_TREE
cout<<"best sibling -> "<<*best<<endl;
#endif
if (pair == best) {
iterator_type parent = t.relocate_parent(node);
assert(parent != t.end());
#if DEBUG_TREE
cout<<"BEST SIBLING MATCHES! relocating..."<<endl;
cout<<" parent -> "<<*parent<<endl;
#endif
// add paired nodes to container
s.insert(node);
s.insert(pair);
// compute best pair for the parent
best = t.sibling(parent);
if (best != t.end()) {
tuple_type tuple = std::make_tuple(parent, best, cost(cost(*parent,*best)));
q.push(tuple);
iterator_type node = std::get<0>(tuple);
iterator_type pair = std::get<1>(tuple);
#if DEBUG_TREE
cout<<" pushing new tuple "<<endl;
cout<<" node -> "<<*node<<endl;
cout<<" pair -> "<<*pair<<endl;
cout<<" volume -> "<<std::get<2>(tuple)<<endl;
#endif
}
}
// else enqueue new pair
else {
if (best != t.end()) {
tuple_type tuple = std::make_tuple(node,best, cost(cost(*node, *best)));
q.push(tuple);
iterator_type node = std::get<0>(tuple);
iterator_type pair = std::get<1>(tuple);
#if DEBUG_TREE
cout<<"BEST SIBLING DOES NOT MATCH!"<<endl;
cout<<" pushing new tuple "<<endl;
cout<<" node -> "<<*node<<endl;
cout<<" pair -> "<<*pair<<endl;
cout<<" volume -> "<<std::get<2>(tuple)<<endl;
#endif
}
}
}
return tp;
}
template <class tree_type>
void print_mathematica(tree_type& t) {
typedef typename tree_type::value_type volume_type;
int d = volume_type::dim();
cout<<std::fixed;
cout.precision(2);
if (d == 2)
cout<<"Graphics[{";
else
cout<<"Graphics3D[{";
for (typename tree_type::const_leaf_iterator it = t.leaves_begin(); it != t.leaves_end(); ++it)
cout<<*it<<", ";
cout<<"}];"<<endl;
}
template <typename T>
std::string stringify(const T& x) {
std::stringstream o;
if (!(o << x)) {
cout<<"*** ERROR *** Bad argument to stringity function"<<endl;
exit(1);
}
return o.str();
}
template <class tree>
void export_video(tree& t, Real duration, Real min_opacity, std::string pre = "", std::string post = "") {
typedef typename tree::value_type volume_type;
typedef typename volume_type::aabb_type aabb_type;
typedef typename aabb_type::point_type point_type;
typedef typename point_type::value_type value_type;
typedef typename tree::iterator iterator;
int d = volume_type::dim();
cout<<std::fixed;
cout.precision(2);
std::tuple<size_t, size_t, size_t> h = t.height();
typename tree::iterator it = t.begin();
aabb_type bb = it->bounding_box();
// get bounding box
for (; it != t.end(); ++it)
bb += it->bounding_box();
std::string figs;
int H = std::get<2>(h);
int k = 0;
for (int l = H; l>=0; --l) {
std::string g = "g";
g += stringify(k);
++k;
// compute opacity for figure
Real opacity = (1 - min_opacity)*static_cast<double>(l)/H + min_opacity;
if (d == 2)
cout<<g<<" = Graphics[{Opacity["<<stringify(opacity)<<"],"<<pre;
else
cout<<g<<" = Graphics3D[{Opacity["<<stringify(opacity)<<"],"<<pre;
t.execute_at_level(l, [](iterator it){ cout<<*it<<", ";});
figs += figs.empty() ? g : (','+g);
cout<<"}];\nShow["<<figs<<", PlotRange-> {{";
const point_type &m = bb.min();
const point_type &M = bb.max();
for (int i=0; i<d; ++i) {
value_type l = 0.05*(M[i] - m[i]);
cout<<(m[i]-l)<<','<<(M[i]+l)<<(i < d-1 ? "},{" : "}}");
}
cout<<post<<"];\n";
cout<<"Export[\""<<g<<".png\", %, ImageResolution -> 300];"<<endl;
}
cout<<"files = Last /@ Sort[{Characters@#, #} & /@ FileNames[\"*.png\"]]"<<endl;
cout<<"images = Map[Import, files];"<<endl;
cout<<"Export[\"video.mov\", images, \"FrameRate\" -> "<<stringify(static_cast<double>(k)/duration)<<"];"<<endl;
}
//// bottom up tree construction
//template <class volume_container>
//Tree<typename volume_container::value_type, Cost_functor<typename volume_container::value_type> >
//construct_tree_bottom_up2(const volume_container& volumes)
//{
//
// typedef typename volume_container::value_type volume_type;
//
// // online tree type definitions
// typedef Tree<volume_type, Cost_functor<volume_type> > tree_type;
//
// typedef Tree_node<volume_type> node_type;
// typedef typename tree_type::link_type link_type;
//
// size_t numVolumes = volumes.size();
// assert(numVolumes != 0);
//
// // allocate leafs of the tree
// link_type* leafs = new link_type[numVolumes];
//
// for (size_t i=0; i<numVolumes; ++i)
// leafs[i] = new node_type(volumes[i]);
//
// while (numVolumes > 1) {
//
// // find indices of the two "nearest" nodes, based on some criterion
// size_t ii,jj;
// Real merged = std::numeric_limits<Real>::infinity();
// for (size_t i=0; i<numVolumes; ++i)
// for (size_t j=i+1; j<numVolumes; ++j) {
//
// volume_type v = leafs[i]->value_ + leafs[j]->value_;
// if (v.measure() < merged) {
// ii = i;
// jj = j;
// merged = v.measure();
// }
// }
//
// volume_type v = leafs[ii]->value_ + leafs[jj]->value_;
// link_type parent = new node_type(v);
//
//#if DEBUG_TREE
// cout<<"best volume found -> "<<v<<endl;
// cout<<"measure -> "<<v.measure()<<endl;
// cout<<"parent -> "<<parent->value_<<endl;
// cout<<"left -> "<<leafs[ii]->value_<<endl;
// cout<<"right -> "<<leafs[jj]->value_<<endl;
//#endif
//
// parent->left_ = leafs[ii];
// parent->right_ = leafs[jj];
// leafs[ii]->parent_ = parent;
// leafs[jj]->parent_ = parent;
//
// // remove the two nodes from the active set and add in the new node.
// leafs[ii] = parent;
// leafs[jj] = leafs[numVolumes - 1];
// --numVolumes;
// }
//
// link_type root = leafs[0];
//
// tree_type t(root);
//
// delete leafs;
//
// return t;
//}
__END_AKANTU__
#endif /* __AKANTU_TREE_HH__ */
diff --git a/src/common/aka_typelist.hh b/src/common/aka_typelist.hh
index a44c7c266..8fa5a6444 100644
--- a/src/common/aka_typelist.hh
+++ b/src/common/aka_typelist.hh
@@ -1,184 +1,184 @@
/**
* @file aka_typelist.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue Jun 17 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Objects that support the visitor design pattern
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TYPELIST_HH__
#define __AKANTU_TYPELIST_HH__
#include "aka_common.hh"
__BEGIN_AKANTU__
struct Empty_type {};
class Null_type {};
template <class T, class U>
struct Typelist {
typedef T Head;
typedef U Tail;
};
template <
typename T1 = Null_type, typename T2 = Null_type, typename T3 = Null_type,
typename T4 = Null_type, typename T5 = Null_type, typename T6 = Null_type,
typename T7 = Null_type, typename T8 = Null_type, typename T9 = Null_type,
typename T10 = Null_type, typename T11 = Null_type, typename T12 = Null_type,
typename T13 = Null_type, typename T14 = Null_type, typename T15 = Null_type,
typename T16 = Null_type, typename T17 = Null_type, typename T18 = Null_type,
typename T19 = Null_type, typename T20 = Null_type
>
struct MakeTypelist
{
private:
typedef typename MakeTypelist
<
T2 , T3 , T4 ,
T5 , T6 , T7 ,
T8 , T9 , T10,
T11, T12, T13,
T14, T15, T16,
T17, T18, T19, T20
>
::Result TailResult;
public:
typedef Typelist<T1, TailResult> Result;
};
template<>
struct MakeTypelist<> {
typedef Null_type Result;
};
////////////////////////////////////////////////////////////////////////////////
// class template Length
// Computes the length of a typelist
// Invocation (TList is a typelist):
// Length<TList>::value
// returns a compile-time constant containing the length of TList, not counting
// the end terminator (which by convention is Null_type)
////////////////////////////////////////////////////////////////////////////////
template <class TList> struct Length;
template <> struct Length<Null_type>
{
enum { value = 0 };
};
template <class T, class U>
struct Length< Typelist<T, U> >
{
enum { value = 1 + Length<U>::value };
};
////////////////////////////////////////////////////////////////////////////////
// class template TypeAt
// Finds the type at a given index in a typelist
// Invocation (TList is a typelist and index is a compile-time integral
// constant):
// TypeAt<TList, index>::Result
// returns the type in position 'index' in TList
// If you pass an out-of-bounds index, the result is a compile-time error
////////////////////////////////////////////////////////////////////////////////
template <class TList, unsigned int index> struct TypeAt;
template <class Head, class Tail>
struct TypeAt<Typelist<Head, Tail>, 0>
{
typedef Head Result;
};
template <class Head, class Tail, unsigned int i>
struct TypeAt<Typelist<Head, Tail>, i>
{
typedef typename TypeAt<Tail, i - 1>::Result Result;
};
////////////////////////////////////////////////////////////////////////////////
// class template Erase
// Erases the first occurence, if any, of a type in a typelist
// Invocation (TList is a typelist and T is a type):
// Erase<TList, T>::Result
// returns a typelist that is TList without the first occurence of T
////////////////////////////////////////////////////////////////////////////////
template <class TList, class T> struct Erase;
template <class T> // Specialization 1
struct Erase<Null_type, T>
{
typedef Null_type Result;
};
template <class T, class Tail> // Specialization 2
struct Erase<Typelist<T, Tail>, T>
{
typedef Tail Result;
};
template <class Head, class Tail, class T> // Specialization 3
struct Erase<Typelist<Head, Tail>, T>
{
typedef Typelist<Head,
typename Erase<Tail, T>::Result>
Result;
};
template <class TList, class T> struct IndexOf;
template <class T>
struct IndexOf<Null_type, T>
{
enum { value = -1 };
};
template <class T, class Tail>
struct IndexOf<Typelist<T, Tail>, T>
{
enum { value = 0 };
};
template <class Head, class Tail, class T>
struct IndexOf<Typelist<Head, Tail>, T>
{
private:
enum { temp = IndexOf<Tail, T>::value };
public:
enum { value = (temp == -1 ? -1 : 1 + temp) };
};
__END_AKANTU__
#endif /* __AKANTU_TYPELIST_HH__ */
diff --git a/src/common/aka_types.hh b/src/common/aka_types.hh
index 5a8c18c9f..6923adc27 100644
--- a/src/common/aka_types.hh
+++ b/src/common/aka_types.hh
@@ -1,1118 +1,1119 @@
/**
* @file aka_types.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 17 2011
- * @date last modification: Tue Aug 19 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief description of the "simple" types
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_error.hh"
#include "aka_fwd.hh"
#include "aka_math.hh"
/* -------------------------------------------------------------------------- */
#include <iomanip>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_TYPES_HH__
#define __AKANTU_AKA_TYPES_HH__
__BEGIN_AKANTU__
enum NormType {
L_1 = 1,
L_2 = 2,
L_inf = UInt(-1)
};
/**
* DimHelper is a class to generalize the setup of a dim array from 3
* values. This gives a common interface in the TensorStorage class
* independently of its derived inheritance (Vector, Matrix, Tensor3)
*/
template<UInt dim>
struct DimHelper {
static inline void setDims(UInt m, UInt n, UInt p, UInt dims[dim]);
};
/* -------------------------------------------------------------------------- */
template<>
struct DimHelper<1> {
static inline void setDims(UInt m,
__attribute__((unused)) UInt n,
__attribute__((unused)) UInt p,
UInt dims[1]) {
dims[0] = m;
}
};
/* -------------------------------------------------------------------------- */
template<>
struct DimHelper<2> {
static inline void setDims(UInt m,
UInt n,
__attribute__((unused)) UInt p,
UInt dims[2]) {
dims[0] = m;
dims[1] = n;
}
};
/* -------------------------------------------------------------------------- */
template<>
struct DimHelper<3> {
static inline void setDims(UInt m,
UInt n,
UInt p,
UInt dims[3]) {
dims[0] = m;
dims[1] = n;
dims[2] = p;
}
};
/* -------------------------------------------------------------------------- */
template<typename T, UInt ndim, class RetType>
class TensorStorage;
/* -------------------------------------------------------------------------- */
/* Proxy classes */
/* -------------------------------------------------------------------------- */
/**
* The TensorProxy class is a proxy class to the TensorStorage it handles the
* wrapped case. That is to say if an accessor should give access to a Tensor
* wrapped on some data, like the Array<T>::iterator they can return a
* TensorProxy that will be automatically transformed as a TensorStorage wrapped
* on the same data
*/
template<typename T, UInt ndim, class RetType>
class TensorProxy {
protected:
TensorProxy(T * data, UInt m, UInt n, UInt p) {
DimHelper<ndim>::setDims(m, n, p, this->n);
this->values = data;
}
TensorProxy(const TensorProxy & other) {
this->values = other.storage();
for (UInt i = 0; i < ndim; ++i)
this->n[i] = other.n[i];
}
inline TensorProxy(const TensorStorage<T, ndim, RetType> & other);
public:
UInt size(UInt i) const {
AKANTU_DEBUG_ASSERT(i < ndim,
"This tensor has only "
<< ndim << " dimensions, not " << (i + 1));
return n[i];
}
inline UInt size() const{
UInt _size = 1;
for (UInt d = 0; d < ndim; ++d) _size *= this->n[d];
return _size;
}
T * storage() const { return values; }
inline TensorProxy & operator=(const RetType & src) {
AKANTU_DEBUG_ASSERT(src.size() == this->size(),
"You are trying to copy two tensors with different sizes");
memcpy(this->values, src.storage(), this->size() * sizeof(T));
return *this;
}
inline TensorProxy & operator=(const TensorProxy & src) {
AKANTU_DEBUG_ASSERT(src.size() == this->size(),
"You are trying to copy two tensors with different sizes");
memcpy(this->values, src.storage(), this->size() * sizeof(T));
return *this;
}
protected:
T * values;
UInt n[ndim];
};
/* -------------------------------------------------------------------------- */
template<typename T>
class VectorProxy : public TensorProxy<T, 1, Vector<T> > {
typedef TensorProxy<T, 1, Vector<T> > parent;
typedef Vector<T> type;
public:
VectorProxy(T * data, UInt n) : parent(data, n, 0, 0) { }
VectorProxy(const VectorProxy & src) : parent(src) { }
VectorProxy(const Vector<T> & src) : parent(src) { }
VectorProxy & operator=(const type & src) {
parent::operator=(src);
return *this;
}
VectorProxy & operator=(const VectorProxy & src) {
parent::operator=(src);
return *this;
}
T & operator()(UInt index){return this->values[index];};
const T & operator()(UInt index) const {return this->values[index];};
};
template<typename T>
class MatrixProxy : public TensorProxy<T, 2, Matrix<T> > {
typedef TensorProxy<T, 2, Matrix<T> > parent;
typedef Matrix<T> type;
public:
MatrixProxy(T * data, UInt m, UInt n) : parent(data, m, n, 0) { }
MatrixProxy(const MatrixProxy & src) : parent(src) { }
MatrixProxy(const type & src) : parent(src) { }
MatrixProxy & operator=(const type & src) {
parent::operator=(src);
return *this;
}
MatrixProxy & operator=(const MatrixProxy & src) {
parent::operator=(src);
return *this;
}
};
template<typename T>
class Tensor3Proxy : public TensorProxy<T, 3, Tensor3<T> > {
typedef TensorProxy<T, 3, Tensor3<T> > parent;
typedef Tensor3<T> type;
public:
Tensor3Proxy(T * data, UInt m, UInt n, UInt k) :
parent(data, m, n, k) { }
Tensor3Proxy(const Tensor3Proxy & src) : parent(src) { }
Tensor3Proxy(const Tensor3<T> & src) : parent(src) { }
Tensor3Proxy & operator=(const type & src) {
parent::operator=(src);
return *this;
}
Tensor3Proxy & operator=(const Tensor3Proxy & src) {
parent::operator=(src);
return *this;
}
};
/* -------------------------------------------------------------------------- */
/* Tensor base class */
/* -------------------------------------------------------------------------- */
template<typename T, UInt ndim, class RetType>
class TensorStorage {
public:
typedef T value_type;
protected:
template<class TensorType>
void copySize(const TensorType & src) {
for (UInt d = 0; d < ndim; ++d) this->n[d] = src.size(d);
this->_size = src.size();
}
TensorStorage() :
values(NULL), wrapped(false) {
for (UInt d = 0; d < ndim; ++d) this->n[d] = 0;
_size = 0;
}
TensorStorage(const TensorProxy<T, ndim, RetType> & proxy) {
this->copySize(proxy);
this->values = proxy.storage();
this->wrapped = true;
}
protected:
TensorStorage(const TensorStorage & src) { }
public:
TensorStorage(const TensorStorage & src, bool deep_copy) :
values(NULL), wrapped(false) {
if(deep_copy) this->deepCopy(src);
else this->shallowCopy(src);
}
protected:
TensorStorage(UInt m, UInt n, UInt p, const T & def) {
DimHelper<ndim>::setDims(m, n, p, this->n);
this->computeSize();
this->values = new T[this->_size];
this->set(def);
this->wrapped = false;
}
TensorStorage(T * data, UInt m, UInt n, UInt p) {
DimHelper<ndim>::setDims(m, n, p, this->n);
this->computeSize();
this->values = data;
this->wrapped = true;
}
public:
/* ------------------------------------------------------------------------ */
template<class TensorType>
inline void shallowCopy(const TensorType & src) {
this->copySize(src);
if(!this->wrapped) delete[] this->values;
this->values = src.storage();
this->wrapped = true;
}
/* ------------------------------------------------------------------------ */
template<class TensorType>
inline void deepCopy(const TensorType & src) {
this->copySize(src);
if(!this->wrapped) delete [] this->values;
this->values = new T[this->_size];
memcpy((void*)this->values, (void*)src.storage(), this->_size * sizeof(T));
this->wrapped = false;
}
virtual ~TensorStorage() {
if(!this->wrapped)
delete [] this->values;
}
/* ------------------------------------------------------------------------ */
inline TensorStorage & operator=(const RetType & src) {
if(this != &src) {
if (this->wrapped) {
// this test is not sufficient for Tensor of order higher than 1
AKANTU_DEBUG_ASSERT(this->_size == src.size(), "Tensors of different size");
memcpy((void*)this->values, (void*)src.storage(), this->_size * sizeof(T));
} else {
deepCopy(src);
}
}
return *this;
}
/* ------------------------------------------------------------------------ */
template<class R>
inline RetType & operator+=(const TensorStorage<T, ndim, R> & other) {
T * a = this->storage();
T * b = other.storage();
AKANTU_DEBUG_ASSERT(_size == other.size(),
"The two tensors do not have the same size, they cannot be subtracted");
for (UInt i = 0; i < _size; ++i) *(a++) += *(b++);
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
template<class R>
inline RetType & operator-=(const TensorStorage<T, ndim, R> & other) {
T * a = this->storage();
T * b = other.storage();
AKANTU_DEBUG_ASSERT(_size == other.size(),
"The two tensors do not have the same size, they cannot be subtracted");
for (UInt i = 0; i < _size; ++i) *(a++) -= *(b++);
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
inline RetType & operator+=(const T & x) {
T * a = this->values;
for (UInt i = 0; i < _size; ++i) *(a++) += x;
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
inline RetType & operator-=(const T & x) {
T * a = this->values;
for (UInt i = 0; i < _size; ++i) *(a++) -= x;
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
inline RetType & operator*=(const T & x) {
T * a = this->storage();
for (UInt i = 0; i < _size; ++i) *(a++) *= x;
return *(static_cast<RetType *>(this));
}
/* ---------------------------------------------------------------------- */
inline RetType & operator/=(const T & x) {
T * a = this->values;
for (UInt i = 0; i < _size; ++i) *(a++) /= x;
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
T * storage() const { return values; }
UInt size() const { return _size; }
UInt size(UInt i) const {
AKANTU_DEBUG_ASSERT(i < ndim,
"This tensor has only "
<< ndim << " dimensions, not " << (i + 1));
return n[i];
};
/* ------------------------------------------------------------------------ */
inline void clear() { memset(values, 0, _size * sizeof(T)); };
inline void set(const T & t) { std::fill_n(values, _size, t); };
template<class TensorType>
inline void copy(const TensorType & other) {
AKANTU_DEBUG_ASSERT(_size == other.size(),
"The two tensors do not have the same size, they cannot be copied");
memcpy(values, other.storage(), _size * sizeof(T));
}
bool isWrapped() const { return this->wrapped; }
protected:
friend class Array<T>;
inline void computeSize() {
_size = 1;
for (UInt d = 0; d < ndim; ++d) _size *= this->n[d];
}
protected:
template<typename R, NormType norm_type>
struct NormHelper {
template<class Ten>
static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it) _norm += std::pow(std::abs(*it), norm_type);
return std::pow(_norm, 1./norm_type);
}
};
template<typename R>
struct NormHelper<R, L_1> {
template<class Ten>
static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it) _norm += std::abs(*it);
return _norm;
}
};
template<typename R>
struct NormHelper<R, L_2> {
template<class Ten>
static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it) _norm += *it * *it;
return sqrt(_norm);
}
};
template<typename R>
struct NormHelper<R, L_inf> {
template<class Ten>
static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it) _norm = std::max(std::abs(*it), _norm);
return _norm;
}
};
public:
/*----------------------------------------------------------------------- */
/// "Entrywise" norm norm<L_p> @f[ \|\boldsymbol{T}\|_p = \left(
/// \sum_i^{n[0]}\sum_j^{n[1]}\sum_k^{n[2]} |T_{ijk}|^p \right)^{\frac{1}{p}}
/// @f]
template<NormType norm_type>
inline T norm() const { return NormHelper<T, norm_type>::norm(*this); }
protected:
UInt n[ndim];
UInt _size;
T * values;
bool wrapped;
};
template<typename T, UInt ndim, class RetType>
inline TensorProxy<T, ndim, RetType>::TensorProxy(const TensorStorage<T, ndim, RetType> & other) {
this->values = other.storage();
for (UInt i = 0; i < ndim; ++i)
this->n[i] = other.size(i);
}
/* -------------------------------------------------------------------------- */
/* Vector */
/* -------------------------------------------------------------------------- */
template<typename T>
class Vector : public TensorStorage< T, 1, Vector<T> > {
typedef TensorStorage< T, 1, Vector<T> > parent;
public:
typedef typename parent::value_type value_type;
typedef VectorProxy<T> proxy;
public:
Vector() : parent() {}
Vector(UInt n, const T & def = T()) : parent(n, 0, 0, def) { }
Vector(T * data, UInt n) : parent(data, n, 0, 0) { }
Vector(const Vector & src, bool deep_copy = true) : parent(src, deep_copy) { }
Vector(const VectorProxy<T> & src) : parent(src) { }
public:
virtual ~Vector() { };
/* ------------------------------------------------------------------------ */
inline Vector & operator=(const Vector & src) {
parent::operator=(src);
return *this;
}
/* ------------------------------------------------------------------------ */
inline T& operator()(UInt i) {
AKANTU_DEBUG_ASSERT((i < this->n[0]),
"Access out of the vector! "
<< "Index (" << i << ") is out of the vector of size ("
<< this->n[0] << ")");
return *(this->values + i);
}
inline const T& operator()(UInt i) const {
AKANTU_DEBUG_ASSERT((i < this->n[0]),
"Access out of the vector! "
<< "Index (" << i << ") is out of the vector of size ("
<< this->n[0] << ")");
return *(this->values + i);
}
inline T& operator[](UInt i) { return *(this->values + i); }
inline const T& operator[](UInt i) const { return *(this->values + i); }
/* ------------------------------------------------------------------------ */
inline Vector<T> & operator*=(Real x) { return parent::operator*=(x); }
inline Vector<T> & operator/=(Real x) { return parent::operator/=(x); }
/* ------------------------------------------------------------------------ */
inline Vector<T> & operator*=(const Vector<T> & vect) {
T * a = this->storage();
T * b = vect.storage();
for (UInt i = 0; i < this->_size; ++i) *(a++) *= *(b++);
return *this;
}
/* ------------------------------------------------------------------------ */
inline Real dot(const Vector<T> & vect) const {
return Math::vectorDot(this->values, vect.storage(), this->_size);
}
/* ------------------------------------------------------------------------ */
inline Real mean() const {
Real mean = 0;
T * a = this->storage();
for (UInt i = 0; i < this->_size; ++i) mean += *(a++);
return mean / this->_size;
}
/* ------------------------------------------------------------------------ */
inline Vector & crossProduct(const Vector<T> & v1,
const Vector<T> & v2) {
AKANTU_DEBUG_ASSERT(this->size() == 3,
"crossProduct is only defined in 3D (n=" << this->size() << ")");
AKANTU_DEBUG_ASSERT(this->size() == v1.size() && this->size() == v2.size(),
"crossProduct is not a valid operation non matching size vectors");
Math::vectorProduct3(v1.storage(), v2.storage(), this->values);
return *this;
}
/* ------------------------------------------------------------------------ */
inline void solve(Matrix<T> & A, const Vector<T> & b) {
AKANTU_DEBUG_ASSERT(this->size() == A.rows() && this->_size = A.cols(),
"The size of the solution vector mismatches the size of the matrix");
AKANTU_DEBUG_ASSERT(this->_size == b._size, "The rhs vector has a mismatch in size with the matrix");
Math::solve(this->_size, A.storage(), this->values, b.storage());
}
/* ------------------------------------------------------------------------ */
template<bool tr_A>
inline void mul(const Matrix<T> & A,
const Vector<T> & x,
Real alpha = 1.0);
/* ------------------------------------------------------------------------ */
inline Real norm() const {
return parent::template norm<L_2>();
}
template<NormType nt>
inline Real norm() const {
return parent::template norm<nt>();
}
/* ------------------------------------------------------------------------ */
inline void normalize() {
Real n = norm();
operator/=(n);
}
/* ------------------------------------------------------------------------ */
/// norm of (*this - x)
inline Real distance(const Vector<T> & y) const {
Real * vx = this->values; Real * vy = y.storage();
Real sum_2 = 0;
for (UInt i = 0; i < this->_size; ++i, ++vx, ++vy) sum_2 += (*vx - *vy)*(*vx - *vy);
return sqrt(sum_2);
}
/* ------------------------------------------------------------------------ */
inline bool equal(const Vector<T> & v, Real tolerance = Math::getTolerance()) const {
T * a = this->storage();
T * b = v.storage();
UInt i = 0;
while (i < this->_size && (std::abs(*(a++) - *(b++)) < tolerance)) ++i;
return i == this->_size;
}
/* ------------------------------------------------------------------------ */
inline short compare(const Vector<T> & v, Real tolerance = Math::getTolerance()) const {
T * a = this->storage();
T * b = v.storage();
for (UInt i(0); i < this->_size; ++i, ++a, ++b) {
if(std::abs(*a - *b) > tolerance)
return (((*a - *b) > tolerance) ? 1 : -1);
}
return 0;
}
/* ------------------------------------------------------------------------ */
inline bool operator==(const Vector<T> & v) const { return equal(v); }
inline bool operator<(const Vector<T> & v) const { return compare(v) == -1; }
inline bool operator>(const Vector<T> & v) const { return compare(v) == 1; }
/* ------------------------------------------------------------------------ */
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << "[";
for (UInt i = 0; i < this->_size; ++i) {
if(i != 0) stream << ", ";
stream << this->values[i];
}
stream << "]";
}
friend class ::akantu::Array<T>;
};
typedef Vector<Real> RVector;
/* ------------------------------------------------------------------------ */
template<>
inline bool Vector<UInt>::equal(const Vector<UInt> & v, __attribute__((unused)) Real tolerance) const {
UInt * a = this->storage();
UInt * b = v.storage();
UInt i = 0;
while (i < this->_size && (*(a++) == *(b++))) ++i;
return i == this->_size;
}
/* ------------------------------------------------------------------------ */
/* Matrix */
/* ------------------------------------------------------------------------ */
template<typename T>
class Matrix : public TensorStorage< T, 2, Matrix<T> > {
typedef TensorStorage< T, 2, Matrix<T> > parent;
public:
typedef typename parent::value_type value_type;
typedef MatrixProxy<T> proxy;
public:
Matrix() : parent() {}
Matrix(UInt m, UInt n, const T & def = T()) : parent(m, n, 0, def) { }
Matrix(T * data, UInt m, UInt n) : parent(data, m, n, 0) { }
Matrix(const Matrix & src, bool deep_copy = true) : parent(src, deep_copy) { }
Matrix(const MatrixProxy<T> & src) : parent(src) { }
virtual ~Matrix() { }
/* ------------------------------------------------------------------------ */
inline Matrix & operator=(const Matrix & src) {
parent::operator=(src);
return *this;
}
public:
/* ---------------------------------------------------------------------- */
UInt rows() const { return this->n[0]; }
UInt cols() const { return this->n[1]; }
/* ---------------------------------------------------------------------- */
inline T& at(UInt i, UInt j) {
AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])),
"Access out of the matrix! "
<< "Index (" << i << ", " << j
<< ") is out of the matrix of size ("
<< this->n[0] << ", " << this->n[1] << ")");
return *(this->values + i + j*this->n[0]);
}
inline const T & at(UInt i, UInt j) const {
AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])),
"Access out of the matrix! "
<< "Index (" << i << ", " << j
<< ") is out of the matrix of size ("
<< this->n[0] << ", " << this->n[1] << ")");
return *(this->values + i + j*this->n[0]);
}
/* ---------------------------------------------------------------------- */
inline T & operator()(UInt i, UInt j) { return this->at(i,j); }
inline const T & operator()(UInt i, UInt j) const { return this->at(i,j); }
/// give a line vector wrapped on the column i
inline VectorProxy<T> operator()(UInt j) {
AKANTU_DEBUG_ASSERT(j < this->n[1], "Access out of the matrix! "
<< "You are trying to access the column vector "
<< j << " in a matrix of size ("
<< this->n[0] << ", " << this->n[1] << ")");
return VectorProxy<T>(this->values + j*this->n[0], this->n[0]);
}
inline const VectorProxy<T> operator()(UInt j) const {
AKANTU_DEBUG_ASSERT(j < this->n[1], "Access out of the matrix! "
<< "You are trying to access the column vector "
<< j << " in a matrix of size ("
<< this->n[0] << ", " << this->n[1] << ")");
return VectorProxy<T>(this->values + j*this->n[0], this->n[0]);
}
inline T& operator[](UInt idx) { return *(this->values + idx); };
inline const T& operator[](UInt idx) const { return *(this->values + idx); };
/* ---------------------------------------------------------------------- */
inline Matrix operator* (const Matrix & B) {
Matrix C(this->rows(), B.cols());
C.mul<false, false>(*this, B);
return C;
}
/* ----------------------------------------------------------------------- */
inline Matrix & operator*= (const T & x) {
return parent::operator*= (x);
}
inline Matrix & operator*= (const Matrix & B) {
Matrix C(*this);
this->mul<false, false>(C, B);
return *this;
}
/* ---------------------------------------------------------------------- */
template<bool tr_A, bool tr_B>
inline void mul(const Matrix & A, const Matrix & B, T alpha = 1.0) {
UInt k = A.cols();
if(tr_A) k = A.rows();
#ifndef AKANTU_NDEBUG
if (tr_B){
AKANTU_DEBUG_ASSERT(k == B.cols(),
"matrices to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->cols() == B.rows(),
"matrices to multiply have no fit dimensions");
}
else {
AKANTU_DEBUG_ASSERT(k == B.rows(),
"matrices to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->cols() == B.cols(),
"matrices to multiply have no fit dimensions");
}
if (tr_A){
AKANTU_DEBUG_ASSERT(this->rows() == A.cols(),
"matrices to multiply have no fit dimensions");
}
else{
AKANTU_DEBUG_ASSERT(this->rows() == A.rows(),
"matrices to multiply have no fit dimensions");
}
#endif //AKANTU_NDEBUG
Math::matMul<tr_A, tr_B>(this->rows(), this->cols(), k,
alpha, A.storage(), B.storage(),
0., this->storage());
}
/* ---------------------------------------------------------------------- */
inline void outerProduct(const Vector<T> & A,
const Vector<T> & B) {
AKANTU_DEBUG_ASSERT(A.size() == this->rows() && B.size() == this->cols(),
"A and B are not compatible with the size of the matrix");
for (UInt i = 0; i < this->rows(); ++i) {
for (UInt j = 0; j < this->cols(); ++j) {
this->values[i + j * this->rows()] += A[i] * B[j];
}
}
}
private:
class EigenSorter {
public:
EigenSorter(const Vector<T> & eigs) : eigs(eigs) { }
bool operator()(const UInt & a, const UInt & b) const {
return (eigs(a) > eigs(b));
}
private:
const Vector<T> & eigs;
};
public:
/* ---------------------------------------------------------------------- */
inline void eig(Vector<T> & eigenvalues, Matrix<T> & eigenvectors) const {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"eig is not a valid operation on a rectangular matrix");
AKANTU_DEBUG_ASSERT(eigenvalues.size() == this->cols(),
"eigenvalues should be of size " << this->cols() << ".");
#ifndef AKANTU_NDEBUG
if(eigenvectors.storage() != NULL)
AKANTU_DEBUG_ASSERT((eigenvectors.rows() == eigenvectors.cols()) &&
(eigenvectors.rows() == this->cols()),
"Eigenvectors needs to be a square matrix of size "
<< this->cols() << " x " << this->cols() << ".");
#endif
Matrix<T> tmp = *this;
Vector<T> tmp_eigs(eigenvalues.size());
Matrix<T> tmp_eig_vects(eigenvectors.rows(), eigenvectors.cols());
if(tmp_eig_vects.rows() == 0 || tmp_eig_vects.cols() == 0)
Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage());
else
Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage(), tmp_eig_vects.storage());
Vector<UInt> perm(eigenvalues.size());
for (UInt i = 0; i < perm.size(); ++i) perm(i) = i;
std::sort(perm.storage(), perm.storage() + perm.size(), EigenSorter(tmp_eigs));
for (UInt i = 0; i < perm.size(); ++i) eigenvalues(i) = tmp_eigs(perm(i));
if(tmp_eig_vects.rows() != 0 && tmp_eig_vects.cols() != 0)
for (UInt i = 0; i < perm.size(); ++i) {
for (UInt j = 0; j < eigenvectors.rows(); ++j) {
eigenvectors(j, i) = tmp_eig_vects(j, perm(i));
}
}
}
/* ---------------------------------------------------------------------- */
inline void eig(Vector<T> & eigenvalues) const {
Matrix<T> empty;
eig(eigenvalues, empty);
}
/* ---------------------------------------------------------------------- */
inline void eye(T alpha = 1.) {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"eye is not a valid operation on a rectangular matrix");
this->clear();
for (UInt i = 0; i < this->cols(); ++i) {
this->values[i + i * this->rows()] = alpha;
}
}
/* ---------------------------------------------------------------------- */
static inline Matrix<T> eye(UInt m, T alpha = 1.) {
Matrix<T> tmp(m, m);
tmp.eye(alpha);
return tmp;
}
/* ---------------------------------------------------------------------- */
inline T trace() const {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"trace is not a valid operation on a rectangular matrix");
T trace = 0.;
for (UInt i = 0; i < this->rows(); ++i) {
trace += this->values[i + i * this->rows()];
}
return trace;
}
/* ---------------------------------------------------------------------- */
inline Matrix transpose() const {
Matrix tmp(this->cols(), this->rows());
for (UInt i = 0; i < this->rows(); ++i) {
for (UInt j = 0; j < this->cols(); ++j) {
tmp(j,i) = operator()(i, j);
}
}
return tmp;
}
/* ---------------------------------------------------------------------- */
inline void inverse(const Matrix & A) {
AKANTU_DEBUG_ASSERT(A.cols() == A.rows(),
"inv is not a valid operation on a rectangular matrix");
AKANTU_DEBUG_ASSERT(this->cols() == A.cols(),
"the matrix should have the same size as its inverse");
if(this->cols() == 1) *this->values = 1./ *A.storage();
else if(this->cols() == 2) Math::inv2(A.storage(), this->values);
else if(this->cols() == 3) Math::inv3(A.storage(), this->values);
else Math::inv(this->cols(), A.storage(), this->values);
}
/* --------------------------------------------------------------------- */
inline T det() const {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"inv is not a valid operation on a rectangular matrix");
if(this->cols() == 1) return *(this->values);
else if(this->cols() == 2) return Math::det2(this->values);
else if(this->cols() == 3) return Math::det3(this->values);
else return Math::det(this->cols(), this->values);
}
/* --------------------------------------------------------------------- */
inline T doubleDot(const Matrix<T> & other) const {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"doubleDot is not a valid operation on a rectangular matrix");
if(this->cols() == 1) return *(this->values) * *(other.storage());
else if(this->cols() == 2) return Math::matrixDoubleDot22(this->values, other.storage());
else if(this->cols() == 3) return Math::matrixDoubleDot33(this->values, other.storage());
else AKANTU_DEBUG_ERROR("doubleDot is not defined for other spatial dimensions"
<< " than 1, 2 or 3.");
return T();
}
/* ---------------------------------------------------------------------- */
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << "[";
for (UInt i = 0; i < this->n[0]; ++i) {
if(i != 0) stream << ", ";
stream << "[";
for (UInt j = 0; j < this->n[1]; ++j) {
if(j != 0) stream << ", ";
stream << operator()(i, j);
}
stream << "]";
}
stream << "]";
};
};
/* ------------------------------------------------------------------------ */
template<typename T>
template<bool tr_A>
inline void Vector<T>::mul(const Matrix<T> & A,
const Vector<T> & x,
Real alpha) {
#ifndef AKANTU_NDEBUG
UInt n = x.size();
if (tr_A){
AKANTU_DEBUG_ASSERT(n == A.rows(), "matrix and vector to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->size() == A.cols(), "matrix and vector to multiply have no fit dimensions");
} else {
AKANTU_DEBUG_ASSERT(n == A.cols(), "matrix and vector to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->size() == A.rows(), "matrix and vector to multiply have no fit dimensions");
}
#endif
Math::matVectMul<tr_A>(A.rows(), A.cols(), alpha, A.storage(), x.storage(), 0., this->storage());
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline std::ostream & operator<<(std::ostream & stream, const Matrix<T> & _this)
{
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline std::ostream & operator<<(std::ostream & stream, const Vector<T> & _this)
{
_this.printself(stream);
return stream;
}
/* ------------------------------------------------------------------------ */
/* Tensor3 */
/* ------------------------------------------------------------------------ */
template<typename T>
class Tensor3 : public TensorStorage< T, 3, Tensor3<T> > {
typedef TensorStorage< T, 3, Tensor3<T> > parent;
public:
typedef typename parent::value_type value_type;
typedef Tensor3Proxy<T> proxy;
public:
Tensor3() : parent() { };
Tensor3(UInt m, UInt n, UInt p, const T & def = T()) : parent(m, n, p, def) { }
Tensor3(T * data, UInt m, UInt n, UInt p) : parent(data, m, n, p) { }
Tensor3(const Tensor3 & src, bool deep_copy = true) : parent(src, deep_copy) { }
public:
/* ------------------------------------------------------------------------ */
inline Tensor3 & operator=(const Tensor3 & src) {
parent::operator=(src);
return *this;
}
/* ---------------------------------------------------------------------- */
inline T& operator()(UInt i, UInt j, UInt k) {
AKANTU_DEBUG_ASSERT((i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the element "
<< "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
<< this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
return *(this->values + (k*this->n[0] + i)*this->n[1] + j);
}
inline const T& operator()(UInt i, UInt j, UInt k) const {
AKANTU_DEBUG_ASSERT((i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the element "
<< "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
<< this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
return *(this->values + (k*this->n[0] + i)*this->n[1] + j);
}
inline MatrixProxy<T> operator()(UInt k) {
AKANTU_DEBUG_ASSERT((k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the slice "
<< k << " in a tensor3 of size ("
<< this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]);
}
inline const MatrixProxy<T> operator()(UInt k) const {
AKANTU_DEBUG_ASSERT((k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the slice "
<< k << " in a tensor3 of size ("
<< this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]);
}
inline MatrixProxy<T> operator[](UInt k) {
return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]);
}
inline const MatrixProxy<T> operator[](UInt k) const {
return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]);
}
};
/* -------------------------------------------------------------------------- */
// support operations for the creation of other vectors
/* -------------------------------------------------------------------------- */
template <typename T>
Vector<T> operator*(const T & scalar, const Vector<T> & a) {
Vector<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Vector<T> operator*(const Vector<T> & a, const T & scalar) {
Vector<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Vector<T> operator/(const Vector<T> & a, const T & scalar) {
Vector<T> r(a);
r /= scalar;
return r;
}
template <typename T>
Vector<T> operator+(const Vector<T> & a, const Vector<T> & b) {
Vector<T> r(a);
r += b;
return r;
}
template <typename T>
Vector<T> operator-(const Vector<T>& a, const Vector<T>& b) {
Vector<T> r(a);
r -= b;
return r;
}
/* -------------------------------------------------------------------------- */
template <typename T>
Matrix<T> operator*(const T & scalar, const Matrix<T>& a) {
Matrix<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Matrix<T> operator*(const Matrix<T>& a, const T & scalar) {
Matrix<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Matrix<T> operator/(const Matrix<T>& a, const T & scalar) {
Matrix<T> r(a);
r /= scalar;
return r;
}
template <typename T>
Matrix<T> operator+(const Matrix<T>& a, const Matrix<T>& b) {
Matrix<T> r(a);
r += b;
return r;
}
template <typename T>
Matrix<T> operator-(const Matrix<T>& a, const Matrix<T>& b) {
Matrix<T> r(a);
r -= b;
return r;
}
__END_AKANTU__
#endif /* __AKANTU_AKA_TYPES_HH__ */
diff --git a/src/common/aka_visitor.hh b/src/common/aka_visitor.hh
index 2496bb850..cd72e500d 100644
--- a/src/common/aka_visitor.hh
+++ b/src/common/aka_visitor.hh
@@ -1,175 +1,175 @@
/**
* @file aka_visitor.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jan 04 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Objects that support the visitor design pattern
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_VISITOR_HH__
#define __AKANTU_VISITOR_HH__
#include "aka_typelist.hh"
__BEGIN_AKANTU__
///////////////////////////////////////////////////////////////////////////
// visitor class template, adapted from the Andrei Alexandrescu's
// "Modern C++ Design"
enum Visit_type { Mutable, Immutable };
template <class T, typename R = void, Visit_type = Mutable>
class StrictVisitor;
template <class T, typename R>
class StrictVisitor<T, R, Mutable>
{
public:
typedef R ReturnType;
typedef T ParamType;
virtual ~StrictVisitor() {}
virtual ReturnType Visit(ParamType&) = 0;
};
template <class T, typename R>
class StrictVisitor<T, R, Immutable>
{
public:
typedef R ReturnType;
typedef const T ParamType;
virtual ~StrictVisitor() {}
virtual ReturnType Visit(ParamType&) = 0;
};
/// class template StrictVisitor (specialization)
template <class Head, class Tail, typename R>
class StrictVisitor<Typelist<Head, Tail>, R, Mutable>
: public StrictVisitor<Head, R, Mutable>, public StrictVisitor<Tail, R, Mutable>
{
public:
typedef R ReturnType;
typedef Head ParamType;
// using StrictVisitor<Head, R>::Visit;
// using StrictVisitor<Tail, R>::Visit;
};
template <class Head, typename R>
class StrictVisitor<Typelist<Head, Null_type>, R, Mutable> : public StrictVisitor<Head, R, Mutable>
{
public:
typedef R ReturnType;
typedef Head ParamType;
using StrictVisitor<Head, R, Mutable>::Visit;
};
template <class Head, class Tail, typename R>
class StrictVisitor<Typelist<Head, Tail>, R, Immutable>
: public StrictVisitor<Head, R, Immutable>, public StrictVisitor<Tail, R, Immutable>
{
public:
typedef R ReturnType;
typedef Head ParamType;
// using StrictVisitor<Head, R>::Visit;
// using StrictVisitor<Tail, R>::Visit;
};
template <class Head, typename R>
class StrictVisitor<Typelist<Head, Null_type>, R, Immutable> : public StrictVisitor<Head, R, Immutable>
{
public:
typedef R ReturnType;
typedef Head ParamType;
using StrictVisitor<Head, R, Immutable>::Visit;
};
////////////////////////////////////////////////////////////////////////////////
// class template NonStrictVisitor
// Implements non-strict visitation (you can implement only part of the Visit
// functions)
//
template <class R>
struct DefaultFunctor {
template <class T>
R operator()(T&) { return R(); }
};
template <class T, typename R = void, Visit_type V = Mutable, class F = DefaultFunctor<R> > class BaseVisitorImpl;
template <class Head, class Tail, typename R, Visit_type V, class F>
class BaseVisitorImpl<Typelist<Head, Tail>, R, V, F>
: public StrictVisitor<Head, R, V>, public BaseVisitorImpl<Tail, R, V, F> {
public:
typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
virtual R Visit(ParamType& h)
{ return F()(h); }
};
template <class Head, typename R, Visit_type V, class F >
class BaseVisitorImpl<Typelist<Head, Null_type>, R, V, F> : public StrictVisitor<Head, R, V>
{
public:
typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
virtual R Visit(ParamType& h)
{ return F()(h); }
};
/// Visitor
template <class R>
struct Strict {};
template <typename R, class TList, Visit_type V = Mutable, template <class> class FunctorPolicy = DefaultFunctor>
class Visitor : public BaseVisitorImpl<TList, R, V, FunctorPolicy<R> > {
public:
typedef R ReturnType;
template <class Visited>
ReturnType GenericVisit(Visited& host) {
StrictVisitor<Visited, ReturnType, V>& subObj = *this;
return subObj.Visit(host);
}
};
template <typename R, class TList, Visit_type V>
class Visitor<R, TList, V, Strict> : public StrictVisitor<TList, R, V> {
public:
typedef R ReturnType;
template <class Visited>
ReturnType GenericVisit(Visited& host) {
StrictVisitor<Visited, ReturnType, V>& subObj = *this;
return subObj.Visit(host);
}
};
__END_AKANTU__
#endif /* __AKANTU_VISITOR_HH__ */
diff --git a/src/common/aka_voigthelper.cc b/src/common/aka_voigthelper.cc
index 3905a4118..0bdc01fe3 100644
--- a/src/common/aka_voigthelper.cc
+++ b/src/common/aka_voigthelper.cc
@@ -1,67 +1,67 @@
/**
* @file aka_voigthelper.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Till Junge <till.junge@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Dec 20 2013
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Voigt indices
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "aka_common.hh"
#include "aka_voigthelper.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <> const UInt VoigtHelper<1>::mat[][1] = {{0}};
template <> const UInt VoigtHelper<2>::mat[][2] = {{0, 2},
{3, 1}};
template <> const UInt VoigtHelper<3>::mat[][3] = {{0, 5, 4},
{8, 1, 3},
{7, 6, 2}};
template <> const UInt VoigtHelper<1>::vec[][2] = {{0, 0}};
template <> const UInt VoigtHelper<2>::vec[][2] = {{0, 0},
{1, 1},
{0, 1},
{1, 0}};
template <> const UInt VoigtHelper<3>::vec[][2] = {{0, 0},
{1, 1},
{2, 2},
{1, 2},
{0, 2},
{0, 1},
{2, 1},
{2, 0},
{1, 0}};
template <> const Real VoigtHelper<1>::factors[] = {1.};
template <> const Real VoigtHelper<2>::factors[] = {1., 1., 1., 2.};
template <> const Real VoigtHelper<3>::factors[] = {1., 1., 1.,
2., 2., 2.};
__END_AKANTU__
diff --git a/src/common/aka_voigthelper.hh b/src/common/aka_voigthelper.hh
index f1bcf9405..4103724dd 100644
--- a/src/common/aka_voigthelper.hh
+++ b/src/common/aka_voigthelper.hh
@@ -1,204 +1,204 @@
/**
* @file aka_voigthelper.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Till Junge <till.junge@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Dec 20 2013
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Helper file for Voigt notation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKA_VOIGTHELPER_HH__
#define __AKA_VOIGTHELPER_HH__
#include "aka_common.hh"
#include "aka_types.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <UInt dim>
class VoigtHelper {
public:
/// transfer the B matrix to a Voigt notation B matrix
inline static void transferBMatrixToSymVoigtBMatrix(const Matrix<Real> & B,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element);
/// transfer the BNL matrix to a Voigt notation B matrix (See Bathe et al. IJNME vol 9, 1975)
inline static void transferBMatrixToBNL(const Matrix<Real> & B,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element);
/// transfer the BL2 matrix to a Voigt notation B matrix (See Bathe et al. IJNME vol 9, 1975)
inline static void transferBMatrixToBL2(const Matrix<Real> & B, const Matrix<Real> & grad_u,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element);
public:
const static UInt size;
// matrix of vector index I as function of tensor indices i,j
const static UInt mat[dim][dim];
// array of matrix indices ij as function of vector index I
const static UInt vec[dim*dim][2];
// factors to multiply the strain by for voigt notation
const static Real factors[dim*(dim-(dim-1)/2)];
};
template <UInt dim> const UInt VoigtHelper<dim>::size = dim*(dim-(dim-1)/2);
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(const Matrix<Real> & B,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element) {
Bvoigt.clear();
for (UInt i = 0; i < dim; ++i)
for (UInt n = 0; n < nb_nodes_per_element; ++n)
Bvoigt(i, i + n*dim) = B(i, n);
if(dim == 2) {
///in 2D, fill the @f$ [\frac{\partial N_i}{\partial x}, \frac{\partial N_i}{\partial y}]@f$ row
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
Bvoigt(2, 1 + n*2) = B(0, n);
Bvoigt(2, 0 + n*2) = B(1, n);
}
}
if(dim == 3) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
Real dndx = B(0, n);
Real dndy = B(1, n);
Real dndz = B(2, n);
///in 3D, fill the @f$ [0, \frac{\partial N_i}{\partial y}, \frac{N_i}{\partial z}]@f$ row
Bvoigt(3, 1 + n*3) = dndz;
Bvoigt(3, 2 + n*3) = dndy;
///in 3D, fill the @f$ [\frac{\partial N_i}{\partial x}, 0, \frac{N_i}{\partial z}]@f$ row
Bvoigt(4, 0 + n*3) = dndz;
Bvoigt(4, 2 + n*3) = dndx;
///in 3D, fill the @f$ [\frac{\partial N_i}{\partial x}, \frac{N_i}{\partial y}, 0]@f$ row
Bvoigt(5, 0 + n*3) = dndy;
Bvoigt(5, 1 + n*3) = dndx;
}
}
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void VoigtHelper<dim>::transferBMatrixToBNL(const Matrix<Real> & B,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element) {
Bvoigt.clear();
//see Finite element formulations for large deformation dynamic analysis,
//Bathe et al. IJNME vol 9, 1975, page 364 B_{NL}
for (UInt i = 0; i < dim; ++i) {
for (UInt m = 0; m < nb_nodes_per_element; ++m) {
for (UInt n = 0; n < dim; ++n) {
//std::cout << B(n, m) << std::endl;
Bvoigt(i * dim + n, m * dim + i) = B(n, m);
}
}
}
//TODO: Verify the 2D and 1D case
}
/* -------------------------------------------------------------------------- */
template<>
inline void VoigtHelper<1>::transferBMatrixToBL2(const Matrix<Real> & B,
const Matrix<Real> & grad_u,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element) {
Bvoigt.clear();
for (UInt j = 0; j < nb_nodes_per_element; ++j)
for (UInt k = 0; k < 2; ++k)
Bvoigt(0, j * 2 + k) = grad_u(k, 0) * B(0, j);
}
/* -------------------------------------------------------------------------- */
template<>
inline void VoigtHelper<3>::transferBMatrixToBL2(const Matrix<Real> & B,
const Matrix<Real> & grad_u,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element) {
Bvoigt.clear();
for (UInt i = 0; i < 3; ++i)
for (UInt j = 0; j < nb_nodes_per_element; ++j)
for (UInt k = 0; k < 3; ++k)
Bvoigt(i, j * 3 + k) = grad_u(k, i) * B(i, j);
for (UInt i = 3; i < 6; ++i) {
for (UInt j = 0; j < nb_nodes_per_element; ++j) {
for (UInt k = 0; k < 3; ++k){
UInt aux = i-3;
for (UInt m = 0; m < 3; ++m) {
if (m != aux) {
UInt index1 = m;
UInt index2 = 3 - m - aux;
Bvoigt(i, j * 3 + k) += grad_u(k, index1) * B(index2, j);
}
}
}
}
}
}
/* -------------------------------------------------------------------------- */
template<>
inline void VoigtHelper<2>::transferBMatrixToBL2(const Matrix<Real> & B,
const Matrix<Real> & grad_u,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element) {
Bvoigt.clear();
for (UInt i = 0; i < 2; ++i)
for (UInt j = 0; j < nb_nodes_per_element; ++j)
for (UInt k = 0; k < 2; ++k)
Bvoigt(i, j * 2 + k) = grad_u(k, i) * B(i, j);
for (UInt j = 0; j < nb_nodes_per_element; ++j) {
for (UInt k = 0; k < 2; ++k) {
for (UInt m = 0; m < 2; ++m) {
UInt index1 = m;
UInt index2 = (2 - 1) - m;
Bvoigt(2, j * 2 + k) += grad_u(k, index1) * B(index2, j);
}
}
}
}
__END_AKANTU__
#endif
diff --git a/src/contact/contact_common.hh b/src/contact/contact_common.hh
index 63837977a..fd78619fa 100644
--- a/src/contact/contact_common.hh
+++ b/src/contact/contact_common.hh
@@ -1,167 +1,167 @@
/**
* @file contact_common.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Wed Sep 17 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Forward declarations for contact classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_CONTACT_COMMON_HH__
#define __AKANTU_CONTACT_COMMON_HH__
#include <map>
#include "aka_visitor.hh"
#include <array/expr.hpp>
#include "cppargparse.hh"
//#define DEBUG_CONTACT 1
__BEGIN_AKANTU__
using std::cout;
using std::endl;
typedef array::Array<1, Real> vector_type;
typedef array::Array<2, Real> matrix_type;
using array::transpose;
//! Enumerated type used for the Contact overloaded operator[] that returns real
// values
enum Contact_parameter_type {
Epsilon,
Alpha,
Multiplier_tol,
Newton_tol,
Multiplier_max_steps,
Newton_max_steps
};
//! Enumerated type used for the Contact overloaded operator[] that returns
// boolean values
enum Contact_flag_type {
Verbose,
Automatic_penalty_parameter
};
//! Discretization types
enum Discretization_type {
Node_to_node,
Node_to_segment,
Segment_to_segment
};
//! Contact type
enum Contact_type {
Self_contact,
No_self_contact
};
struct EmptyType {};
class NullType {};
//! This functor is called when the visitor is not implemented for a particular
// object.
template <class R> struct Discretization_visitor_default {
template <class T> R operator()(T &t) {
cout << "*** WARNING *** No implementation for discretization visitor"
<< endl;
}
};
template <Discretization_type d> class Contact_discretization;
typedef Contact_discretization<Node_to_node> N2N_c;
typedef Contact_discretization<Node_to_segment> N2S_c;
typedef Contact_discretization<Segment_to_segment> S2S_c;
template <AnalysisMethod s, ContactResolutionMethod r,
ContactImplementationMethod i = _none>
struct SelectResolution {
constexpr static const AnalysisMethod analysis = s;
constexpr static const ContactResolutionMethod method = r;
constexpr static const ContactImplementationMethod implementation = i;
};
template <int Dim, AnalysisMethod s, ContactResolutionMethod r>
class ContactResolution;
template <int Dim, template <int> class Search_policy, class Resolution_policy>
class Contact;
// parsers
extern cppargparse::ArgumentParser contact_argparser;
extern Parser contact_parser;
class ContactParameters {
protected:
typedef std::map<Contact_parameter_type, Real> options_map;
typedef std::map<Contact_flag_type, bool> flag_map;
options_map options_;
flag_map flags_;
public:
//! Overloaded operator[] (const) that returns real values
Real operator[](Contact_parameter_type p) const {
auto it = options_.find(p);
assert(it != options_.end());
return it->second;
}
//! Overloaded operator[] (non-const) that returns real values
Real &operator[](Contact_parameter_type p) { return options_[p]; }
//! Overloaded operator[] (const) that returns flags
bool operator[](Contact_flag_type f) const {
auto it = flags_.find(f);
return it->second;
}
//! Overloaded operator[] (non-const) that returns bool values
bool &operator[](Contact_flag_type p) { return flags_[p]; }
virtual void initialize() {}
};
template <typename T> T Heaviside(T v) { return v < 0 ? 0 : 1; }
template <typename T> T Macauley(T v) { return v < 0 ? 0 : v; }
template <typename value_type = Real> array::Array<2, value_type> eye(UInt d) {
array::Array<2, value_type> I(d);
for (UInt i = 0; i < d; ++i)
I(i, i) = 1.;
return I;
}
__END_AKANTU__
#endif /* __AKANTU_CONTACT_COMMON_HH__ */
diff --git a/src/contact/contact_impl.cc b/src/contact/contact_impl.cc
index 96a12b10e..49d7017e4 100644
--- a/src/contact/contact_impl.cc
+++ b/src/contact/contact_impl.cc
@@ -1,41 +1,42 @@
/**
* @file contact_impl.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Contat class Interface
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
__BEGIN_AKANTU__
/// Paser for commandline arguments
::cppargparse::ArgumentParser contact_argparser;
/// Parser containing the information parsed by the input file given to initFull
Parser contact_parser;
__END_AKANTU__
diff --git a/src/contact/contact_impl.hh b/src/contact/contact_impl.hh
index 88711758d..3e7595d8b 100644
--- a/src/contact/contact_impl.hh
+++ b/src/contact/contact_impl.hh
@@ -1,97 +1,97 @@
/**
* @file contact_impl.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Contact interface class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
//
// contact.hh
// akantu
//
// Created by Alejandro Marcos Aragón on 6/24/14.
//
//
#ifndef __AKANTU_CONTACT_HH__
#define __AKANTU_CONTACT_HH__
#include "contact_common.hh"
#include "parser.hh"
#include "search.hh"
#include "resolution.hh"
__BEGIN_AKANTU__
template <int Dim, template <int> class Search_policy, class RP>
class Contact : public Search_policy<Dim>, public ContactResolution <Dim, RP::analysis, RP::method> {
typedef SolidMechanicsModel model_type;
typedef Search_policy<Dim> search_type;
typedef ContactResolution <Dim, RP::analysis, RP::method> resolution_type;
public:
Contact(int argc, char *argv[], model_type & m) : search_type(m), resolution_type(m)
{
// read parameters from file
std::pair <Parser::const_section_iterator, Parser::const_section_iterator>
sub_sect = getStaticParser().getSubSections(_st_contact);
if (sub_sect.first != sub_sect.second)
this->parseSection(*sub_sect.first);
// read parameters the command line
contact_argparser.parse(argc, argv, cppargparse::_remove_parsed);
// finish initialization of resolution class
this->initialize();
}
//! Provide standard output of contact object
friend std::ostream& operator << (std::ostream & os, const Contact &cd) {
const resolution_type& r(cd);
const search_type& s(cd);
os << "\nContact object info:" << endl;
os << " Search type: " << s << endl;
os << " Resolution type: " << r << endl;
return os;
}
};
template <ContactImplementationMethod i, class contact_type>
void solveContactStep(contact_type& c)
{ c.solveContactStep<i>(&c); }
__END_AKANTU__
#endif /* __AKANTU_CONTACT_HH__ */
diff --git a/src/contact/contact_manager.hh b/src/contact/contact_manager.hh
index 5536fdc39..ecc112ce4 100644
--- a/src/contact/contact_manager.hh
+++ b/src/contact/contact_manager.hh
@@ -1,432 +1,432 @@
/**
* @file contact_manager.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Wed Mar 13 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact manager
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_CMANAGER_HH__
#define __AKANTU_CMANAGER_HH__
#include "aka_common.hh"
#include "surface.hh"
#include "zone.hh"
#include "element.hh"
__BEGIN_AKANTU__
template <int d>
class BBox_sorter {
typedef CSurface<d> surface_type;
struct Comparator {
template <class surface_pointer>
bool operator()(surface_pointer s1, surface_pointer s2) const {
typedef typename surface_type::bbox_type bbox_type;
auto b1 = s1->bounding_box();
auto b2 = s2->bounding_box();
// consider min point for sorting (chosen arbitrarily)
return b1.min(d-1) < b2.min(d-1);
// NOTE: point coordinates are 0-based, so calling d-1 with
// dimension 2 actually gets the second element of the
// coordinate array
}
};
public:
template <class pointer>
static std::pair<pointer, pointer> check(pointer p1, pointer p2) {
typedef std::pair<pointer, pointer> contact_pair;
return p1 < p2 ? contact_pair(p1,p2) : contact_pair(p2,p1);
}
template <class surface_container, class intersection_container>
static void sort(surface_container& surfaces, intersection_container& intersections) {
typedef typename surface_container::value_type surface_ptr;
typedef typename surface_type::bbox_type bbox_type;
typedef typename surface_container::iterator surface_iterator;
typedef typename intersection_container::value_type contact_pair;
// sort container
surfaces.sort(Comparator());
// loop over sorted surfaces
surface_iterator it1 = surfaces.begin();
surface_iterator it2 = ++surfaces.begin();
for (; it2 != surfaces.end(); ++it2) {
// check for intersection of bounding boxes
auto b1 = (*it1)->bounding_box();
auto b2 = (*it2)->bounding_box();
// if bounding boxes intersect
if (b1 & b2) {
// add pair to set
intersections.insert(check(*it1,*it2));
++it1;
} else {
// remove pair from set
intersections.erase(check(*it1,*it2));
// remove first surface from container, as it does not
// intersect other surfaces
surfaces.erase(it1++);
}
}
if (surfaces.size() > 1)
BBox_sorter<d-1>::sort(surfaces, intersections);
}
};
//! Partial template specialization for zero dimension
/*! This class finishes the recursion on dimension by doing nothing in the
* sort function.
*/
template <>
struct BBox_sorter<0> {
template <class surface_container, class intersection_container>
static void sort(surface_container&, intersection_container&) {}
};
template <int d>
class CManager {
typedef SolidMechanicsModel model_type;
typedef CSurface<d> contact_surface;
typedef std::vector<contact_surface> surface_container;
typedef typename surface_container::iterator surface_iterator;
typedef typename surface_container::const_iterator const_surface_iterator;
typedef CZone<d> contact_zone;
typedef std::list<contact_zone*> zone_container;
typedef typename zone_container::iterator zone_iterator;
typedef typename zone_container::const_iterator const_zone_iterator;
typedef CElement<d> contact_element;
typedef std::list<contact_element> celement_container;
typedef typename celement_container::const_iterator celement_iterator;
SolidMechanicsModel &model_;
surface_container surfaces_;
zone_container zones_;
celement_container celements_;
Contact_type c_;
public:
void clear() {
zones_.clear();
celements_.clear();
}
CManager(model_type& model, Contact_type c = No_self_contact_t) : model_(model), c_(c) {
// get mesh from model
Mesh &mesh = model.getMesh();
// call update current position to be able to call later
// the function to get current positions
model.updateCurrentPosition();
// obtain exterior surfaces
MeshUtils::buildFacets(mesh);
// assign surface ids
MeshUtils::buildSurfaceID(mesh);
// allocate memory for surfaces
UInt nb_surfaces = mesh.getNbSurfaces();
surfaces_.reserve(nb_surfaces);
for (UInt i=0; i<nb_surfaces; ++i)
surfaces_.push_back(contact_surface(model));
// iterate over elements of lower dimension
Mesh::type_iterator it = mesh.firstType(d-1);
Mesh::type_iterator end = mesh.lastType(d-1);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it);
UInt nb_nodes = mesh.getNbNodesPerElement(*it);
const Array<UInt> &conn = mesh.getConnectivity(*it);
Array<UInt> &surf_id = mesh.getSurfaceID(*it);
// add elements to corresponding surface
for(UInt e = 0; e < nb_element; ++e) {
CSurface<d> &surface = surfaces_.at(surf_id(e));
surface.add_element(*it,e);
// add element nodes to surface
for (UInt n = 0; n<nb_nodes; ++n)
surface.add_node(conn(e, n));
}
}
}
~CManager() {
// delete over contact zones
for (zone_iterator it = zones_.begin(); it != zones_.end(); ++it)
delete *it;
}
void global_search() {
#ifdef DEBUG_CONTACT
cout<<"__________________________________________________________"<<endl;
cout<<"*** INFO *** Printing contact manager after global search."<<endl;
#endif
typedef const contact_surface* surface_ptr;
typedef std::list<surface_ptr> surface_list;
typedef std::pair<surface_ptr, surface_ptr> contact_pair;
typedef std::set<contact_pair> intersection_container;
typedef typename intersection_container::iterator intersection_iterator;
typedef typename contact_surface::bbox_type bbox_type;
// create container of bounding boxes used for the sort and
// the container to store intersections
surface_list list;
intersection_container intersections;
// loop over surfaces to update bounding boxes
for (surface_iterator it = surfaces_.begin(); it != surfaces_.end(); ++it) {
const contact_surface &surface = *it;
it->update_bounding_box();
list.push_back(&surface);
}
// carry out sort in all dimensions to check for intersections
BBox_sorter<d>::sort(list, intersections);
if (!intersections.empty()) {
// loop over intersections to find contact zones
for (intersection_iterator it = intersections.begin();
it != intersections.end(); ++it) {
// get contact surfaces that intersect
const contact_surface &surface1 = *it->first;
const contact_surface &surface2 = *it->second;
// find intersection bounding box
bbox_type bb = surface1.bounding_box() && surface2.bounding_box();
// find elements that intersect with the above bounding box
std::set<const Element*> intersected_elements;
surface1.intersects(bb, intersected_elements);
#if DEBUG_CONTACT
UInt inter = intersected_elements.size();
cout<<"Surface 1 contains "<<inter<<" elements in contact zone."<<endl;
#endif
surface2.intersects(bb, intersected_elements);
#if DEBUG_CONTACT
cout<<"Surface 2 contains "<<(intersected_elements.size() - inter)<<" elements in contact zone."<<endl;
#endif
// if intersected_elements container is not empty, a contact zone can be created
if (!intersected_elements.empty()) {
// now that the intersection has been found, get contact
// zone object using bounding box and intersecting elements
zones_.push_back(new contact_zone(model_, bb,intersected_elements, surface1, surface2));
}
}
}
#ifdef DEBUG_CONTACT
cout<<*this;
#endif
}
void local_search() {
typedef typename contact_zone::node_set node_set;
typedef typename contact_zone::node_iterator node_iterator;
typedef typename contact_zone::element_container element_set;
typedef typename contact_zone::element_iterator element_iterator;
// loop over contact zones
for (zone_iterator it = zones_.begin(); it != zones_.end(); ++it) {
contact_zone& cs = **it;
// loop over buckets in current contact zone
// incrementation of the iterator is done when removing the bucket taking
// care of not invalidating the iterators
for (typename contact_zone::bucket_iterator bit = cs.buckets_begin(); bit != cs.buckets_end();) {
// get nodes of bucket plus those of contiguous buckets
element_set contiguous = cs.contiguous(bit->first);
const Element* closest = NULL;
// flagged nodes in case that a node belongs to several buckets
// (node in bucket boundaries)
node_set flaggedNodes;
// loop over nodes
for (node_iterator nit1 = bit->second.begin(); nit1 != bit->second.end(); ++nit1) {
auto np = *nit1;
// node has already been considered for a contact element,
// do nothing further with it
node_iterator fit = flaggedNodes.find(np);
if (fit != flaggedNodes.end())
continue;
Real m = std::numeric_limits<Real>::infinity();
// loop over elements
for (element_iterator sit = contiguous.begin(); sit != contiguous.end(); ++sit) {
// checkf if no self-contact is allowed
if (c_ == No_self_contact_t)
if (cs.in_surface(np, *sit)) {
#ifdef DEBUG_CONTACT
cout<<"*** INFO *** Node "<<np<<" and element "<<(*sit)->element<<" belong to the same surface"<<endl;
#endif
continue;
}
// check if node pointed by np lies in the same segment
if (cs.in_element(np, *sit)) {
#ifdef DEBUG_CONTACT
cout<<"*** INFO *** Node "<<np<<" belongs to element "<<*sit<<endl;
#endif
continue;
}
// compute distance from node to element using SQP
Real length = distance<d>(np, *sit, model_);
if (length < m) {
m = length;
closest = *sit;
}
} // loop over elements
// if a close node was found that does not belong to the
// same element, add contact element for resolution
if (closest) {
celements_.push_back(contact_element(np, closest, model_));
flaggedNodes.insert(np);
}
#ifdef DEBUG_CONTACT
else
cout<<"*** INFO *** No close element was found for node "<<np<<endl;
#endif
} // loop over nodes in bucket
// remove bucket for further search as it is not needed
cs.erase_bucket(bit++);
} // loop over buckests
#ifdef DEBUG_CONTACT
// print contact elements
print_celements(cout);
#endif
} // loop over contact zones
}
void remove_penetrations() {
// loop over contact elements
for (celement_iterator eit = celements_.begin(); eit != celements_.end(); ++eit) {
bool flag = eit->penetrates();
if (flag) {
#ifdef DEBUG_CONTACT
cout<<"*** WARNING *** Penetration occurs for element "<<*eit<<endl;
#endif
cout<<"*** INFO *** Collision detected, aborting..."<<endl;
exit(1);
// eit->remove_penetration();
}
}
// clear non-permanent objects
clear();
}
void print_celements(std::ostream& os) {
os<<" Contact elements: "<<celements_.size()<<endl;
for (celement_iterator eit = celements_.begin(); eit != celements_.end(); ++eit)
os<<*eit;
}
//! Enable std output
friend std::ostream& operator<<(std::ostream& os, const CManager& cm) {
os<<"Contact manager info: "<<endl;
os<<" Contact surfaces: "<<cm.surfaces_.size()<<endl;
typename CManager::const_surface_iterator it = cm.surfaces_.begin();
for (; it != cm.surfaces_.end(); ++it)
os<<*it;
os<<" Contact zones: "<<cm.zones_.size()<<endl;
for (typename CManager::const_zone_iterator it = cm.zones_.begin(); it != cm.zones_.end(); ++it)
os<<**it;
return os;
}
};
__END_AKANTU__
#endif /* __AKANTU_CMANAGER_HH__ */
diff --git a/src/contact/discretization.cc b/src/contact/discretization.cc
index 831af325b..0b5ce4dd3 100644
--- a/src/contact/discretization.cc
+++ b/src/contact/discretization.cc
@@ -1,30 +1,31 @@
/**
* @file discretization.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Mon Jul 09 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
diff --git a/src/contact/discretization.hh b/src/contact/discretization.hh
index d8f1da054..c219b13a6 100644
--- a/src/contact/discretization.hh
+++ b/src/contact/discretization.hh
@@ -1,130 +1,130 @@
/**
* @file discretization.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact discretization classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DISCRETIZATION_HH__
#define __AKANTU_DISCRETIZATION_HH__
//#include <cassert>
//#include <stdio.h>
//#include <stdlib.h>
#include <map>
#include "aka_common.hh"
//#include "aka_types.hh"
//#include "contact_common.hh"
//#include "solid_mechanics_model.hh"
#include "solid_mechanics_model_element.hh"
//#include "friction.hh"
using std::endl;
using std::cout;
__BEGIN_AKANTU__
class Discretization_base {
//! Support the visitor design pattern
// virtual void accept(Contact_discretization_visitor&) = 0;
};
template <Discretization_type d>
class Contact_discretization;
//template <>
//class Contact_discretization<Node_to_node> : public Discretization_base {
//
// template <int> friend class Contact_scheme;
//
//private:
//
// // pair structure
// struct N2N_pair {
//
// typedef UInt node_id;
//
// node_id master_, slave_;
// bool contact_, stick_;
// vector_type n_;
// };
//
//
//};
//template <>
//class Contact_discretization<Node_to_segment> : public Discretization_base {
//
//
// typedef SolidMechanicsModel model_type;
// typedef ModelElement <model_type> element_type;
//
// typedef std::map <UInt, element_type> slave_master_map;
// typedef std::map <UInt, Real> real_map;
//
// typedef typename real_map::iterator real_iterator;
// typedef std::map <UInt, Real> gap_map;
//
// slave_master_map sm_;
// real_map areas_, gaps_;
//
//public:
//
// //! Add slave
// void addSlave(UInt s)
// { sm_[s] = element_type(); }
//
// //! Add slave-master pair
// void addPair(UInt s, element_type el)
// { sm_[s] = el; }
//
// //! Add area to a slave node
// void addArea(UInt n, Real a)
// { if (a != 0.) areas_[n] = a; }
//
//
//// //! Member function to support the visitor design pattern.
//// void accept(Contact_discretization_visitor& guest)
//// { guest.GenericVisit(*this); }
//
//};
__END_AKANTU__
#endif /* __AKANTU_DISCRETIZATION_HH__ */
diff --git a/src/contact/element.cc b/src/contact/element.cc
index 1c907121b..060881c80 100644
--- a/src/contact/element.cc
+++ b/src/contact/element.cc
@@ -1,306 +1,306 @@
/**
* @file element.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue May 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact element classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "element.hh"
#include "aka_math.hh"
#include "aka_geometry.hh"
#if defined(AKANTU_BOOST_CHRONO) && !defined(AKANTU_NDEBUG)
# include <boost/chrono.hpp>
#endif
__BEGIN_AKANTU__
template <>
bool check_penetration<2>(UInt node, const Element* el, SolidMechanicsModel& model) {
typedef Point<2> point_type;
Mesh& mesh = model.getMesh();
const Array<Real> &x = model.getCurrentPosition();
const Array<UInt> &conn = mesh.getConnectivity(el->type);
point_type r(&x(node));
// NOTE: switch on a enumerated type is a sign of a bad
// object-oriented design
switch (el->type) {
case _segment_2:
{
// get element extreme points
point_type p(&x(conn(el->element,0)));
point_type q(&x(conn(el->element,1)));
return left_turn(p, q, r) > 0;
}
break;
default:
cout<<"*** ERROR *** Function signed measure in file "<<__FILE__<<", line "<<__LINE__;
cout<<", is not implemented for element of type "<<el->type<<endl;
cout<<"*** ABORTING *** "<<endl;
exit(1);
break;
}
}
template <>
bool check_penetration<3>(UInt node, const Element* el, SolidMechanicsModel& model) {
typedef Point<3> point_type;
Mesh& mesh = model.getMesh();
const Array<Real> &x = model.getCurrentPosition();
const Array<UInt> &conn = mesh.getConnectivity(el->type);
point_type r(&x(node));
// NOTE: switch on a enumerated type is a sign of a bad
// object-oriented design
switch (el->type) {
case _triangle_3:
{
// get element extreme points
point_type o(&x(conn(el->element,0)));
point_type p(&x(conn(el->element,1)));
point_type q(&x(conn(el->element,2)));
// get signed volume
point_type po = o - p;
point_type pq = q - p;
point_type pr = r - p;
// cross product
point_type c = cross(pq, po);
Real v = pr*c;
return v < 0;
}
break;
default:
cout<<"*** ERROR *** Function signed measure in file "<<__FILE__<<", line "<<__LINE__;
cout<<", is not implemented for element of type "<<el->type<<endl;
cout<<"*** ABORTING *** "<<endl;
exit(1);
break;
}
}
template <>
Point<2> minimize_distance<2>(UInt node, const Element* el, SolidMechanicsModel& model) {
const UInt d = 2;
typedef Point<d> point_type;
const Array<Real> &x = model.getCurrentPosition();
point_type r(&x(node));
// NOTE: switch on a enumerated type is a sign of a bad
// object-oriented design
switch (el->type) {
case _segment_2:
{
#if AKANTU_OPTIMIZATION
Distance_minimzer<_segment_2> data(&x(node), el, model);
return data.point();
#else
AKANTU_DEBUG_ERROR("To use this function you should activate the optimization at compile time");
return Point<2>();
#endif
}
break;
default:
cout<<"*** ERROR *** Function signed measure in file "<<__FILE__<<", line "<<__LINE__;
cout<<", is not implemented for element of type "<<el->type<<endl;
cout<<"*** ABORTING *** "<<endl;
exit(1);
break;
}
assert(false);
return point_type(); // avoid compiler warning: control reaches end of non-void function
}
template <>
Point<3> minimize_distance<3>(UInt node, const Element* el, SolidMechanicsModel& model) {
const UInt d = 3;
typedef Point<d> point_type;
const Array<Real> &x = model.getCurrentPosition();
point_type r(&x(node));
// NOTE: switch on a enumerated type is a sign of a bad
// object-oriented design
switch (el->type) {
case _triangle_3:
{
#if AKANTU_OPTIMIZATION
Distance_minimzer<_triangle_3> data(&x(node), el, model);
#if defined(AKANTU_BOOST_CHRONO) && !defined(AKANTU_NDEBUG)
typedef boost::chrono::high_resolution_clock clock_type;
typedef typename clock_type::time_point time_type;
time_type start = clock_type::now();
#endif
data.optimize();
#if defined(AKANTU_BOOST_CHRONO) && !defined(AKANTU_NDEBUG)
boost::chrono::nanoseconds ns = clock_type::now() - start;
cout<<data.iterations()<<"\t"<<ns.count()<<endl;
#endif
// cout<<data.point()<<endl;
return data.point();
#else
AKANTU_DEBUG_ERROR("To use this function you should activate the optimization at compile time");
return Point<3>();
#endif
// const UInt nb_nodes = 3;
//
// // get triangle coordinates from element and point coordinates
// Mesh& mesh = model.getMesh();
// std::vector<point_type> pts(nb_nodes);
//
// const Array<UInt> &conn = mesh.getConnectivity(el->type);
// for (UInt i=0; i<nb_nodes; ++i)
// for (UInt j=0; j<d; ++j)
// pts.at(i)[j] = x(conn(el->element,i),j);
//
// // get closest point
// time_type start = clock_type::now();
//
// Point<3> q = naive_closest_point_to_triangle(r,pts[0],pts[1],pts[2]);
//
// boost::chrono::nanoseconds ns = clock_type::now() - start;
// cout<<ns.count()<<endl;
//
//// static unsigned int k = 0;
//// if (sqrt((q - data.point()).sq_norm()) > 1e-2) {
//// cout<<++k<<endl;
//// cout<<"difference"<<endl;
//// cout<<data.point()<<endl;
//// cout<<q<<endl;
//// cout<<" iter -> "<<data.iterations()<<endl;
//// }
//
//
// return q;
// const UInt nb_nodes = 3;
//
// // get triangle coordinates from element and point coordinates
// Mesh& mesh = model.getMesh();
// std::vector<point_type> pts(nb_nodes);
//
// const Array<UInt> &conn = mesh.getConnectivity(el->type);
// for (UInt i=0; i<nb_nodes; ++i)
// for (UInt j=0; j<d; ++j)
// pts.at(i)[j] = x(conn(el->element,i),j);
//
// // get closest point
// time_type start2 = clock_type::now();
//
// Point<3> q = closest_point_to_triangle(r,pts[0],pts[1],pts[2]);
//
// boost::chrono::nanoseconds ns2 = clock_type::now() - start2;
// cout<<ns2.count()<<endl;
// cout<<q<<endl;
//
// static unsigned int k = 0;
// Real diff = sqrt((q - data.point()).sq_norm());
// if (diff > 1e-8) {
// cout<<"diff -> "<<diff<<endl;
// cout<<++k<<endl;
// cout<<data.point()<<endl;
// cout<<q<<endl;
// cout<<" iter -> "<<data.iterations()<<endl;
// }
//
//
// return q;
}
break;
case _triangle_6:
{
#if AKANTU_OPTIMIZATION
Distance_minimzer<_triangle_6> data(&x(node), el, model);
#if defined(AKANTU_BOOST_CHRONO) && !defined(AKANTU_NDEBUG)
time_type start = clock_type::now();
#endif
data.optimize();
#if defined(AKANTU_BOOST_CHRONO) && !defined(AKANTU_NDEBUG)
boost::chrono::nanoseconds ns = clock_type::now() - start;
cout<<data.iterations()<<"\t"<<ns.count()<<endl;
#endif
return data.point();
#else
AKANTU_DEBUG_ERROR("To use this function you should activate the optimization at compile time");
return Point<3>();
#endif
}
break;
default:
cout<<"*** ERROR *** Function signed measure in file "<<__FILE__<<", line "<<__LINE__;
cout<<", is not implemented for element of type "<<el->type<<endl;
cout<<"*** ABORTING *** "<<endl;
exit(1);
break;
}
assert(false);
return point_type(); // avoid compiler warning: control reaches end of non-void function
}
__END_AKANTU__
diff --git a/src/contact/element.hh b/src/contact/element.hh
index 7498e33af..4c647794a 100644
--- a/src/contact/element.hh
+++ b/src/contact/element.hh
@@ -1,148 +1,148 @@
/**
* @file element.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Wed Mar 13 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact element classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_CELEMENT_HH__
#define __AKANTU_CELEMENT_HH__
#include <iostream>
#include "aka_common.hh"
#include "aka_point.hh"
#include "solid_mechanics_model.hh"
#include "mesh.hh"
#include "contact_common.hh"
#if AKANTU_OPTIMIZATION
# include "aka_optimize.hh"
#endif
__BEGIN_AKANTU__
using std::cout;
using std::endl;
// compute signed measure, used to find out if a node penetrates or not
template <int d>
bool check_penetration(UInt node, const Element* el, SolidMechanicsModel& model);
template <int d>
Point<d> minimize_distance(UInt node, const Element* el, SolidMechanicsModel& model);
template <int d>
Real distance(UInt node, const Element* el, SolidMechanicsModel& model) {
typedef Point<d> point_type;
const Array<Real> &x = model.getCurrentPosition();
// get point of node
point_type o(&x(node));
// compute closest location within the element to master node
point_type p = minimize_distance<d>(node, el, model);
return sqrt((o-p).sq_norm());
}
template <int d>
class CElement {
typedef Point<d> point_type;
typedef const Element* element_pointer;
UInt master_; //!< Slave node
element_pointer element_; //!< Master surface element
SolidMechanicsModel& model_;
public:
CElement(UInt n, element_pointer el, SolidMechanicsModel& model) : master_(n), element_(el), model_(model) {}
//! Checks if there is penetration between the master node and the element
bool penetrates() const {
#ifdef DEBUG_CONTACT
cout<<"*** INFO *** Checking penetration for"<<*this<<endl;
#endif
return check_penetration<d>(master_, element_, model_);
}
void remove_penetration() const {
#ifdef DEBUG_CONTACT
cout<<"*** INFO *** Removing penetration for master node "<<master_<<endl;
#endif
cout<<"before calling minimize distance"<<endl;
// compute closest location within the element to master node
point_type o = minimize_distance<d>(master_, element_, model_);
cout<<"after calling minimize"<<endl;
cout<<"point obtained -> "<<o<<endl;
// modify master node coordinates
Array<Real> &X = model_.getDisplacement();
const Array<Real> &coord = model_.getMesh().getNodes();
for (UInt i=0; i<d; ++i)
X(master_, i) = o[i] - coord(master_, i);
cout<<"after modifying master node coords"<<endl;
}
//! Enable std output
friend std::ostream& operator<<(std::ostream& os, const CElement& cel) {
Mesh& mesh = cel.model_.getMesh();
const Array<Real> &x = cel.model_.getCurrentPosition();
UInt nb_nodes = mesh.getNbNodesPerElement((cel.element_)->type);
const Array<UInt> &conn = mesh.getConnectivity((cel.element_)->type);
os<<" Contact element: "<<endl;
os<<" slave node: "<<cel.master_<<", coordinates: "<<point_type(&x(cel.master_))<<endl;
os<<" master surface element: "<<*cel.element_<<", with extreme nodes";
for (int i=0; i<d; ++i)
os<<" - "<<point_type(&x(conn((cel.element_)->element, i)));
os<<endl;
return os;
}
};
__END_AKANTU__
#endif /* __AKANTU_CELEMENT_HH__ */
diff --git a/src/contact/friction.cc b/src/contact/friction.cc
index 26e2024d1..af0dd5501 100644
--- a/src/contact/friction.cc
+++ b/src/contact/friction.cc
@@ -1,36 +1,37 @@
/**
* @file friction.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jan 04 2013
+ * @date creation: Mon Jul 09 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact friction classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "friction.hh"
__BEGIN_AKANTU__
__END_AKANTU__
diff --git a/src/contact/friction.hh b/src/contact/friction.hh
index 87b705419..29e89eafa 100644
--- a/src/contact/friction.hh
+++ b/src/contact/friction.hh
@@ -1,98 +1,98 @@
/**
* @file friction.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jan 04 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact friction classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_FRICTION_HH__
#define __AKANTU_FRICTION_HH__
#include <iostream>
#include <cmath>
#include "aka_common.hh"
__BEGIN_AKANTU__
using std::cout;
using std::endl;
enum Friction_type { Coulomb_t, Prakash_Clifton_t, Rate_state_t, Rice_t };
// base class for all contract friction concrete classes,
// used so that friction classes can be stored in a container
// if needed
struct Contact_friction_base {};
template <int>
class Contact_friction;
// partial template specialization for Coulomb friction
template <>
class Contact_friction<Coulomb_t> : public Contact_friction_base {
typedef Contact_friction_base base_type;
typedef Real value_type;
protected:
value_type mu_; // coefficient of friction
public:
Contact_friction() : base_type(), mu_() {}
Contact_friction(value_type mu) : base_type(), mu_(mu) {}
void setFriction(value_type mu)
{ mu_ = mu; }
value_type friction() const
{ return mu_; }
value_type computeForceMagnitude(value_type Pn)
{ return mu_*Pn; }
template <class vector_type>
value_type computeForceMagnitude(const vector_type& P) {
value_type norm = value_type();
for (int i=0; i<P.size(); ++i)
norm += pow(mu_*P[i], 2.);
return sqrt(norm);
}
};
__END_AKANTU__
#endif /* __AKANTU_FRICTION_HH__ */
diff --git a/src/contact/resolution.hh b/src/contact/resolution.hh
index c60349fdc..4eaaa3d05 100644
--- a/src/contact/resolution.hh
+++ b/src/contact/resolution.hh
@@ -1,39 +1,40 @@
/**
* @file resolution.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Mon Sep 15 2014
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact resolution classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_RESOLUTION_HH__
#define __AKANTU_RESOLUTION_HH__
#include "resolution_augmented_lagrangian.hh"
#endif /* __AKANTU_RESOLUTION_HH__ */
diff --git a/src/contact/resolution/resolution_augmented_lagrangian.cc b/src/contact/resolution/resolution_augmented_lagrangian.cc
index f2d58e5f4..5e415fbd4 100644
--- a/src/contact/resolution/resolution_augmented_lagrangian.cc
+++ b/src/contact/resolution/resolution_augmented_lagrangian.cc
@@ -1,1283 +1,1283 @@
/**
* @file resolution_augmented_lagrangian.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Wed Sep 17 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact resolution classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
//#include "resolution_augmented_lagrangian.hh"
#include "resolution_augmented_lagrangian.hh"
#define COUT(name) std::cout << std::string(#name) << ": " << name << std::endl;
__BEGIN_AKANTU__
template <int Dim>
void ContactResolution<Dim, _static, _augmented_lagrangian>::initialize() {
// give priority to command line arguments instead of those in a file
if (contact_argparser.has("aka_penalty"))
options_[Epsilon] = contact_argparser["aka_penalty"];
else
flags_[Automatic_penalty_parameter] = true;
if (contact_argparser.has("aka_alpha"))
options_[Alpha] = contact_argparser["aka_alpha"];
if (contact_argparser.has("aka_utol"))
options_[Multiplier_tol] = contact_argparser["aka_utol"];
if (contact_argparser.has("aka_ntol"))
options_[Newton_tol] = contact_argparser["aka_ntol"];
if (contact_argparser.has("aka_usteps"))
options_[Multiplier_max_steps] = contact_argparser["aka_usteps"];
if (contact_argparser.has("aka_nsteps"))
options_[Newton_max_steps] = contact_argparser["aka_nsteps"];
if (contact_argparser.has("aka_verbose"))
flags_[Verbose] = true;
}
template <int Dim>
ContactResolution<Dim, _static, _augmented_lagrangian>::ContactResolution(
model_type &m)
: Parsable(_st_contact), model_(m),
multiplier_dumper_(m.getMesh().getNbNodes(), 3),
pressure_dumper_(m.getMesh().getNbNodes(), 3) {
// register dumpers
m.getMesh().addDumpFieldExternal("multipliers", multiplier_dumper_);
m.getMesh().addDumpFieldExternal("pressure", pressure_dumper_);
// register parameters from the file
registerParam("penalty", options_[Epsilon], _pat_parsable,
"Penalty parameter for Augmented-Lagrangian formulation");
registerParam("alpha", options_[Alpha], 1., _pat_parsable,
"Multiplier for values of the penalty parameter");
registerParam("utol", options_[Multiplier_tol], 1e-4, _pat_parsable,
"Tolerance used for multipliers in the Uzawa method");
registerParam("ntol", options_[Newton_tol], 1e-4, _pat_parsable,
"Tolerance used in the Newton-Raphson inner convergence loop");
registerParam("usteps", options_[Multiplier_max_steps], 100., _pat_parsable,
"Maximum number of steps allowed in the Uzawa loop");
registerParam("nsteps", options_[Newton_max_steps], 100., _pat_parsable,
"Maximum number of steps allowed in the Newton-Raphson loop");
// register parameters from the command line
contact_argparser.addArgument(
"--aka_penalty", "Penalty parameter for Augmented-Lagrangian formulation",
1, cppargparse::_float);
contact_argparser.addArgument(
"--aka_alpha", "Multiplier for values of the penalty parameter", 1,
cppargparse::_float);
contact_argparser.addArgument(
"--aka_utol", "Tolerance used for multipliers in the Uzawa method", 1,
cppargparse::_float);
contact_argparser.addArgument(
"--aka_ntol",
"Tolerance used in the Newton-Raphson inner convergence loop", 1,
cppargparse::_float);
contact_argparser.addArgument(
"--aka_usteps", "Maximum number of steps allowed in the Uzawa loop", 1,
cppargparse::_float);
contact_argparser.addArgument(
"--aka_nsteps",
"Maximum number of steps allowed in the Newton-Raphson loop", 1,
cppargparse::_float);
contact_argparser.addArgument("--aka_verbose", "Verbose output flag", 0,
cppargparse::_boolean);
}
template <int Dim>
void
ContactResolution<Dim, _static, _augmented_lagrangian>::solveContactStepImpl(
SearchBase *sp, Int2Type<_generalized_newton> gn) {
ContactResolution &cd = *this;
model_.implicitPred();
model_.updateResidual();
AKANTU_DEBUG_ASSERT(model_.stiffness_matrix != NULL,
"You should first initialize the implicit solver and "
"assemble the stiffness matrix");
//** comments that start like this will comment on the work that has to be
//** done for the implementation of the frictional terms in the code
UInt k = 0;
UInt ntotal = 0;
std::list<int> nt;
// get global stiffness matrix and force vector
SparseMatrix &K = model_.getStiffnessMatrix();
Array<Real> &F = model_.getResidual();
// get size of the whole system
UInt original = model_.increment->getSize() * Dim;
UInt size = original + sm_.size();
//** the size variable at this point is computed by adding only the number
//** of slave nodes because for each slave node there's a lagrangian
//** multiplier for the normal contact assigned to it. In the case of
//** frictional contact, this variable will have to account for 2 (3)
//** multipliers for each in slave node in 2D (3D), accounting for the
//** tangential components.
contact_status_ = std::map<UInt, bool>();
status_change_ = std::map<UInt, int>();
size_t ccc = 0;
for (auto g : gaps_) {
if (std::abs(g.second) <= 1.e-10) {
contact_status_[g.first] = true;
++ccc;
}
}
Array<Real> solution(size);
Array<Real> rhs(size);
rhs.clear();
// extend data structures to consider Lagrange multipliers
K.resize(size);
//** with the right value of the 'size' variable, all these data structures
//** will be resized accordingly
cout << std::boolalpha;
if (cd[Verbose])
cout << "- Start Generalized Newton:" << endl;
UInt j = 0;
bool converged = false;
bool converged_multiplier = false;
Real fnorm = 0;
do {
Real nerror = 0.;
cd.niter_ = j;
// assemble material matrix
model_.assembleStiffnessMatrix();
// copy residual to rhs
std::copy_n(F.storage(), original, rhs.storage());
// compute contribution to tangent matrix and residual
Real dummy;
computeTangentAndResidual(solution, rhs, sp, dummy, gn);
//** The computeTangentAndResidual is where the major development for the
//** frictional part will take place.
//** All the terms coded in this function into the stiffness matrix and the
//** force vector take into account only the normal contact component. The
//** implementation of the frictional part will include terms for the
//** tangential multipliers. The process I followed for the implementation
//** was to code the stiffness matrix terms from the book by Laursen
//** (Computational Contact and Impact Mechanics). I then took the terms
//** involving the lagrangian multiplier part from the thesis by Grzegorz
//** Pietrzak (Continuum mechanics modelling and augmented Lagrangian
//** formulation of large deformation frictional contact problems) as
//** these terms were missing in the Laursen book. Some little changes had
//** to be made into these terms, as Laursen and Pietrzak use different
//** conventions for the sign of the gap function. In Pietrzak's thesis,
//** the residual terms are given following Eqn. 6.20 (page 146), and the
//** stiffness terms in following equation 6.25 (page 149).
//** I suggest to start by the implementation of the Uzawa method, as it is
//** not required to code the tangential lagrangian multiplier terms of
//** Pietrzak
// solve
model_.template solve<IntegrationScheme2ndOrder::_displacement_corrector>(
solution, 1., true, true, rhs);
// copy the solution of the system to increment for the primal variable only
std::copy_n(solution.begin(), model_.increment->getSize() * Dim,
model_.increment->storage());
// copy the solution of the system to increment for the lagrange multiplier
size_t m = 0;
std::vector<Real> multiplier_check(multipliers_.size());
vector_type v_old(multipliers_.size());
vector_type v_new(v_old);
for (auto &pair : multipliers_) {
v_old[m] = pair.second;
v_new[m] = v_old[m] + solution[original + m];
multiplier_check[m] = pair.second;
multipliers_[pair.first] += solution[original + m];
multiplier_check[m] -= pair.second;
++m;
}
Real sum_multiplier = 0.;
for (auto m : multiplier_check)
sum_multiplier += m * m;
//** this check basically computes the L_2 norm of the lagrange multiplier
//** difference, so this test may change when implementing the frictional
//** part
Real mnorm = sqrt(sum_multiplier);
Real abs_tol = cd[Multiplier_tol];
if (j == 0)
fnorm = mnorm;
converged_multiplier =
(mnorm <= abs_tol || mnorm <= abs_tol * abs_tol * fnorm);
model_.implicitCorr();
model_.updateResidual();
converged =
model_.template testConvergence<_scc_increment>(cd[Newton_tol], nerror);
if (cd[Verbose]) {
size_t w = 10;
cout << std::setw(2) << j << ": Primal: " << std::setw(w)
<< std::setprecision(4) << std::right << nerror
<< " <= " << cd[Newton_tol] << " = " << std::left << std::setw(5)
<< (nerror < cd[Newton_tol]) << " \tDual: " << std::setw(w)
<< std::setprecision(4) << std::right << mnorm
<< " <= " << cd[Multiplier_tol] << " = "
<< (mnorm <= cd[Multiplier_tol]) << ", " << std::setw(w) << mnorm
<< " <= " << abs_tol * abs_tol * fnorm << " = "
<< (mnorm <= abs_tol * abs_tol * fnorm) << endl;
}
++j;
AKANTU_DEBUG_INFO("[" << _scc_increment << "] Convergence iteration "
<< std::setw(std::log10(cd[Newton_max_steps])) << j
<< ": error " << nerror << (converged ? " < " : " > ")
<< cd[Newton_tol] << std::endl);
} while (!(converged && converged_multiplier) && j < cd[Newton_max_steps]);
if (j == cd[Newton_max_steps]) {
cout << "*** ERROR *** Newton-Raphson loop did not converge within max "
"number of iterations: " << cd[Newton_max_steps] << endl;
exit(1);
}
nt.push_back(j);
ntotal += j;
AKANTU_DEBUG_INFO("[" << _scc_increment << "] Uzawa convergence iteration "
<< std::setw(std::log10(cd[Newton_max_steps])) << k
<< std::endl);
cout << "Generalized Newton iterations: " << j << endl;
// dump vtk files
this->dump();
}
template <int Dim>
void
ContactResolution<Dim, _static, _augmented_lagrangian>::solveContactStepImpl(
SearchBase *sp, Int2Type<_uzawa> uz) {
ContactResolution &cd = *this;
model_.implicitPred();
model_.updateResidual();
AKANTU_DEBUG_ASSERT(model_.stiffness_matrix != NULL,
"You should first initialize the implicit solver and "
"assemble the stiffness matrix");
//** comments that start like this will comment on the work that has to be
//** done for the implementation of the frictional terms in the code
// implementation of the Uzawa method for solving contact
bool uzawa_converged = false;
static UInt step = 0;
UInt k = 0;
UInt ntotal = 0;
std::list<int> nt;
std::ofstream ofs;
ofs.open("iterations.out", std::ofstream::out | std::ofstream::app);
// initialize Lagrange multipliers
// NOTE: It doesn't make any difference to start from the previous
// converged solution of Lagrange multipliers
real_map lambda_new;
cout << std::boolalpha;
if (cd[Verbose])
cout << "- Start Uzawa:" << endl;
do {
Real uerror = 0.;
bool converged = false;
UInt j = 0;
cd.uiter_ = k;
do {
Real nerror = 0.;
cd.niter_ = j;
// assemble material matrix
model_.assembleStiffnessMatrix();
// compute contribution to tangent matrix and residual
uzawa_converged = computeTangentAndResidual(lambda_new, sp, uerror, uz);
//** The computeTangentAndResidual is where the major development for the
//** frictional part will take place.
//** All the terms coded in this function into the stiffness matrix and
//** the force vector take into account only the normal contact component.
//** The implementation of the frictional part will include terms for the
//** tangential multipliers. The process I followed for the implementation
//** was to code the stiffness matrix terms from the book by Laursen
//** (Computational Contact and Impact Mechanics).
//** I suggest you start by the implementing the Uzawa method first,
//** before jumping to the more involved implementation of the tangential
//** lagrangian multiplier terms of Pietrzak
// solve
model_.template solve<IntegrationScheme2ndOrder::_displacement_corrector>(
*model_.increment, 1., true, true);
model_.implicitCorr();
model_.updateResidual();
converged = model_.template testConvergence<_scc_increment>(
cd[Newton_tol], nerror);
if (cd[Verbose])
cout << " Newton: " << j << ", " << nerror << " < " << cd[Newton_tol]
<< " = " << (nerror < cd[Newton_tol]) << endl;
++j;
AKANTU_DEBUG_INFO("[" << _scc_increment << "] Convergence iteration "
<< std::setw(std::log10(cd[Newton_max_steps])) << j
<< ": error " << nerror
<< (converged ? " < " : " > ") << cd[Newton_tol]
<< std::endl);
} while (!converged && j < cd[Newton_max_steps]);
if (cd[Verbose])
cout << " Uzawa: " << k << ", " << uerror << " < " << cd[Multiplier_tol]
<< " = " << (uerror < cd[Multiplier_tol]) << endl;
if (j == cd[Newton_max_steps]) {
cout << "*** ERROR *** Newton-Raphson loop did not converge within max "
"number of iterations: " << cd[Newton_max_steps] << endl;
exit(1);
}
nt.push_back(j);
ntotal += j;
// increment uzawa loop counter
++k;
AKANTU_DEBUG_INFO("[" << _scc_increment << "] Uzawa convergence iteration "
<< std::setw(std::log10(cd[Newton_max_steps])) << k
<< std::endl);
// update lagrange multipliers
cd.multipliers_ = lambda_new;
} while (!uzawa_converged && k < cd[Multiplier_max_steps]);
if (k == cd[Multiplier_max_steps]) {
cout << "*** ERROR *** Uzawa loop did not converge within max number of "
"iterations: " << cd[Multiplier_max_steps] << endl;
exit(1);
}
cout << "Summary: Uzawa [" << k << "]: Newton [" << ntotal << "]:";
for (int n : nt)
cout << " " << n;
cout << endl;
ofs << std::setw(10) << ++step << std::setw(10) << k << std::setw(10)
<< ntotal << endl;
ofs.close();
this->dump();
}
template <int Dim>
void ContactResolution<Dim, _static, _augmented_lagrangian>::dump() {
multiplier_dumper_.clear();
pressure_dumper_.clear();
for (auto v : multipliers_) {
element_type &el = sm_[v.first];
if (el == element_type())
continue;
auto n = el.normal();
Real lambda = v.second;
for (size_t i = 0; i < n.size(); ++i)
multiplier_dumper_(v.first, i) = lambda * n[i];
// dump pressures only if area is associated with node
auto it = areas_.find(v.first);
if (it != areas_.end())
for (size_t i = 0; i < n.size(); ++i) {
Real a = it->second;
assert(a != 0.);
pressure_dumper_(v.first, i) = lambda * n[i] / a;
}
else
cout << "*** WARNING *** Zero area for slave node " << v.first << endl;
}
model_.dump();
}
template <int Dim>
void
ContactResolution<Dim, _static, _augmented_lagrangian>::getPenaltyValues() {
cout << "*** INFO *** Obtaining penalty parameters automatically. ";
const SparseMatrix &Kconst = model_.getStiffnessMatrix();
Real ave = 0.;
size_t k = 0;
// loop over pairs
for (auto it = sm_.begin(); it != sm_.end(); ++it) {
auto slave = it->first;
auto master = it->second;
if (master != element_type()) {
std::vector<UInt> conn(master.numNodes() + 1); // 1 slave (not hardcoded)
conn[0] = slave;
for (UInt i = 0; i < master.numNodes(); ++i)
conn[1 + i] = master.node(i);
// compute normal
vector_type nu = master.normal();
// carry out stiffness multiplication with the normal
// the product Kij*nj would give the force for a unit displacement
// (i.e., the stiffness needed to move the node by 1)
matrix_type r(Kconst.getSize(), master.numNodes() + 1);
// loop over stifness matrix dimension
for (size_t i = 0; i < Kconst.getSize(); ++i)
// loop over problem dimensions
for (int j = 0; j < Dim; ++j)
// loop over nodes considered
for (size_t k = 0; k < master.numNodes() + 1; ++k)
r(i, k) += Kconst(i, conn[k] + j) * nu(j);
// get results (norm of each column in r)
vector_type rsum(master.numNodes() + 1);
for (size_t i = 0; i < rsum.size(); ++i)
for (size_t j = 0; j < r.rows(); ++j)
rsum(i) += r(j, i) * r(j, i);
// get average value as the penalty parameter
Real epsilon = 0.;
for (size_t i = 0; i < rsum.size(); ++i)
epsilon += sqrt(rsum(i));
epsilon /= master.numNodes() + 1;
penalty_[slave] = epsilon;
ave += penalty_[slave];
++k;
}
// dummy master
else {
// carry out stiffness multiplication with the normal
// the product Kij*nj would give the force for a unit displacement
// (i.e., the stiffness needed to move the node by 1)
vector_type r(Kconst.getSize());
// loop over stifness matrix dimension
for (size_t i = 0; i < Kconst.getSize(); ++i)
// loop over problem dimensions
for (int j = 0; j < Dim; ++j)
// loop over nodes considered
r(i) += Kconst(i, slave + j) * 1. / Dim;
// get results (norm of each column in r)
Real epsilon = 0;
for (size_t i = 0; i < r.size(); ++i)
epsilon += r(i) * r(i);
epsilon = sqrt(epsilon);
penalty_[slave] = epsilon;
ave += penalty_[slave];
++k;
}
}
cout << "Average value: " << (*this)[Alpha] * ave / k << endl;
}
template <int dim> struct TangentTraits;
template <> struct TangentTraits<2> {
constexpr static UInt dim = 2;
constexpr static ElementType master_type = _segment_2;
constexpr static InterpolationType interpolation_type =
_itp_lagrange_segment_2;
typedef Point<dim> point_type;
typedef array::Array<1, Real> vector_type;
typedef array::Array<2, Real> matrix_type;
typedef SolidMechanicsModel model_type;
template <class element_type>
static bool projects(const point_type &s, const element_type &master,
const Array<Real> &position) {
return has_projection(s, point_type(&position(master.node(0))),
point_type(&position(master.node(1))));
}
template <class real_tuple, class element_type, class vector_type>
static std::tuple<matrix_type, vector_type>
computeTangentAndResidual(model_type &model, real_tuple t,
element_type &master, const vector_type &sh,
const matrix_type &dsh, const vector_type &N) {
const Array<Real> &position = model.getCurrentPosition();
Real gap = std::get<0>(t);
Real s1 = std::get<1>(t);
Real s2 = std::get<2>(t);
// compute the point on the surface
point_type a(&position(master.node(0)));
point_type b(&position(master.node(1)));
vector_type nu = master.normal();
// compute vector T
point_type tau = dsh(0, 0) * a + dsh(0, 1) * b;
vector_type T(dim * (master.numNodes() + 1));
for (UInt i = 0; i < dim; ++i) {
T[i] = tau[i];
for (UInt j = 0; j < master.numNodes(); ++j)
T[(1 + j) * dim + i] = -tau[i] * sh[j];
}
// compute N1
vector_type N1(dim * (master.numNodes() + 1));
for (UInt i = 0; i < dim; ++i) {
for (UInt j = 0; j < master.numNodes(); ++j)
N1[(1u + j) * dim + i] = -nu[i] * dsh(0u, j);
}
// compute m11
Real m11 = tau * tau;
// compute D1
vector_type D1 = T + gap * N1;
D1 *= 1. / m11;
// Note: N1bar = N1 - k11*D1, but since k11 = 0 for 2D, then
// N1bar = N1
vector_type &N1bar = N1;
// stiffness matrix (only non-zero terms for 2D implementation)
matrix_type kc = s1 * N * transpose(N); // first term
kc += (s2 * gap * m11) * N1bar * transpose(N1bar); // second term
kc -= s2 * D1 * transpose(N1); // sixth term
kc -= s2 * N1 * transpose(D1); // eight term
// residual vector
vector_type fc = s2 * N;
assert(kc.rows() == fc.size());
return std::make_tuple(kc, fc);
}
template <class element_type>
static std::tuple<point_type, vector_type>
compute_projection(const point_type &s, element_type &master) {
Distance_minimizator<dim, master_type> dm(s, master.coordinates());
vector_type xi(1, dm.master_coordinates()[0]);
return std::make_tuple(dm.point(), xi);
}
};
template <> struct TangentTraits<3> {
constexpr static UInt dim = 3;
constexpr static ElementType master_type = _triangle_3;
constexpr static InterpolationType interpolation_type =
_itp_lagrange_triangle_3;
typedef Point<dim> point_type;
typedef array::Array<1, Real> vector_type;
typedef array::Array<2, Real> matrix_type;
typedef SolidMechanicsModel model_type;
template <class element_type>
static bool projects(const point_type &s, const element_type &master,
const Array<Real> &position) {
return point_has_projection_to_triangle(
s, point_type(&position(master.node(0))),
point_type(&position(master.node(1))),
point_type(&position(master.node(2))));
}
template <class real_tuple, class element_type, class vector_type>
static std::tuple<matrix_type, vector_type>
computeTangentAndResidual(model_type &model, real_tuple t,
element_type &master, const vector_type &sh,
const matrix_type &dsh, const vector_type &N) {
const Array<Real> &position = model.getCurrentPosition();
Real gap = std::get<0>(t);
Real s1 = std::get<1>(t);
Real s2 = std::get<2>(t);
Real s3 = std::get<3>(t);
// compute the point on the surface
point_type a(&position(master.node(0)));
point_type b(&position(master.node(1)));
point_type c(&position(master.node(2)));
vector_type nu = master.normal();
point_type tau1 = dsh(0, 0) * a + dsh(0, 1) * b + dsh(0, 2) * c;
point_type tau2 = dsh(1, 0) * a + dsh(1, 1) * b + dsh(1, 2) * c;
vector_type nucheck(3);
Math::vectorProduct3(&tau1[0], &tau2[0], &nucheck[0]);
Math::normalize3(&nucheck[0]);
if ((nucheck - nu)().norm() > 1.0e-10) {
cout << "*** ERROR *** Normal failed" << endl;
cout << "nu1: " << nu << endl;
cout << "nu2: " << nucheck << endl;
exit(1);
}
// compute vectors T1, T2, N1, N2
size_t vsize = dim * (master.numNodes() + 1);
vector_type T1(vsize), T2(vsize), N1(vsize), N2(vsize);
for (UInt i = 0; i < dim; ++i) {
T1[i] = tau1[i];
T2[i] = tau2[i];
for (UInt j = 0; j < master.numNodes(); ++j) {
T1[(1 + j) * dim + i] = -tau1[i] * sh[j];
T2[(1 + j) * dim + i] = -tau2[i] * sh[j];
N1[(1 + j) * dim + i] = -nu[i] * dsh(0u, j);
N2[(1 + j) * dim + i] = -nu[i] * dsh(1u, j);
}
}
// compute matrix A = m + k*g (but kappa is zero for linear elements)
Real A11 = tau1 * tau1;
Real A12 = tau1 * tau2;
Real A22 = tau2 * tau2;
Real detA = A11 * A22 - A12 * A12;
// compute vectors D1, D2
vector_type D1 =
(1 / detA) * (A22 * (T1 + gap * N1)() - A12 * (T2 + gap * N2)())();
vector_type D2 =
(1 / detA) * (A11 * (T2 + gap * N2)() - A12 * (T1 + gap * N1)())();
// Note: N1bar = N1 - k12*D2, but since k12 = 0 for linear elements, then
// N1bar = N1, N2bar = N2
vector_type &N1bar = N1;
vector_type &N2bar = N2;
// stiffness matrix (only non-zero terms for 3D implementation with linear
// elements)
// get covariant terms (det(A) = det(inv(A))
Real m11 = A22 / detA;
Real m12 = -A12 / detA;
Real m22 = A11 / detA;
// 1st term:
// epsilon * Heaviside(lambda + epsilon gap) * N * N' = s1 * N * N'
matrix_type kc = s1 * N * transpose(N);
// 2nd term:
// t_N * gap * m_11 * N1_bar * N1_bar', where t_N = <lambda + epsilon*gap>
kc += (s3 * m11) * N1bar * transpose(N1bar);
// 3rd and 4th terms:
// t_N * gap * m_12 * (N1_bar * N2_bar' + N2_bar * N1_bar')
matrix_type tmp = N1bar * transpose(N2bar);
tmp += N2bar * transpose(N1bar);
kc += (s3 * m12) * tmp;
// 5th term:
// t_N * gap * m_22 * N2_bar * N2_bar'
kc += (s3 * m22) * N2bar * transpose(N2bar);
// 6th term:
// - t_N * D1 * N1'
kc -= s2 * D1 * transpose(N1);
// 7th term:
// - t_N * D2 * N2'
kc -= s2 * D2 * transpose(N2);
// 8th term:
// - t_N * N1 * D1'
kc -= s2 * N1 * transpose(D1);
// 9th term:
// - t_N * N2 * D2'
kc -= s2 * N2 * transpose(D2);
// residual vector
vector_type fc = s2 * N;
assert(kc.rows() == fc.size());
return std::make_tuple(kc, fc);
}
//! Function template specialization for inversion of a \f$ 3 \times 3 \f$
// matrix.
template <class matrix_type>
static std::pair<matrix_type, Real> invert(matrix_type &A) {
// obtain determinant of the matrix
Real det = A[0][0] * (A[1][1] * A[2][2] - A[1][2] * A[2][1]) -
A[0][1] * (A[1][0] * A[2][2] - A[1][2] * A[2][0]) +
A[0][2] * (A[1][0] * A[2][1] - A[1][1] * A[2][0]);
// compute inverse
matrix_type inv(3, 3, 1. / det);
inv[0][0] *= A[1][1] * A[2][2] - A[1][2] * A[2][1];
inv[0][1] *= A[0][2] * A[2][1] - A[0][1] * A[2][2];
inv[0][2] *= -A[0][2] * A[1][1] + A[0][1] * A[1][2];
inv[1][0] *= A[1][2] * A[2][0] - A[1][0] * A[2][2];
inv[1][1] *= A[0][0] * A[2][2] - A[0][2] * A[2][0];
inv[1][2] *= A[0][2] * A[1][0] - A[0][0] * A[1][2];
inv[2][0] *= -A[1][1] * A[2][0] + A[1][0] * A[2][1];
inv[2][1] *= A[0][1] * A[2][0] - A[0][0] * A[2][1];
inv[2][2] *= -A[0][1] * A[1][0] + A[0][0] * A[1][1];
return std::make_pair(inv, det);
}
template <class vector_type, class point_type>
static vector_type invert_map(const point_type &s, const point_type &a,
const point_type &b, const point_type &c) {
typedef array::Array<2, Real> matrix_type;
// matrix for inverse
matrix_type A = { { b[0] - a[0], c[0] - a[0], a[0] },
{ b[1] - a[1], c[1] - a[1], a[1] },
{ b[2] - a[2], c[2] - a[2], a[2] } };
std::pair<matrix_type, Real> Ainv = invert(A);
vector_type x = { s[0], s[1], s[2] };
vector_type r1 = Ainv.first * x;
return vector_type{ r1[0],
r1[1] }; // return only the first two components of r1
}
template <class element_type>
static std::tuple<point_type, vector_type>
compute_projection(const point_type &s, element_type &master) {
auto coord = master.coordinates();
// compute the point on the surface
point_type a(coord[0]);
point_type b(coord[1]);
point_type c(coord[2]);
point_type p = closest_point_to_triangle(s, a, b, c);
vector_type xi = invert_map<vector_type, point_type>(p, a, b, c);
// Distance_minimizator<dim, TangentTraits<dim>::master_type> dm(
// s, master.coordinates());
// xi = vector_type(dim - 1);
// for (int i = 0; i < dim - 1; ++i)
// xi[i] = dm.master_coordinates()[i];
// point_type p = dm.point();
return std::make_tuple(p, xi);
}
};
template <int dim>
bool ContactResolution<dim, _static, _augmented_lagrangian>::
computeTangentAndResidual(real_map &lambda_new, SearchBase *cp, Real &error,
Int2Type<_uzawa>) {
const Array<Real> &position = model_.getCurrentPosition();
const Real tol = (*this)[Multiplier_tol];
// get global stiffness matrix and force vector
SparseMatrix &K = model_.getStiffnessMatrix();
Array<Real> &F = model_.getResidual();
const Array<Int> &eqnum =
model_.getDOFSynchronizer().getLocalDOFEquationNumbers();
static bool auto_flag = true;
if (auto_flag) {
auto_flag = false;
if (!(*this)[Automatic_penalty_parameter]) {
Real epsilon = (*this)[Epsilon];
for (auto it = sm_.begin(); it != sm_.end(); ++it)
penalty_[it->first] = epsilon;
cout << "*** INFO *** Uniform penalty parameter used for all slaves: "
<< epsilon << endl;
;
}
// else get penalty values automatically
else
getPenaltyValues();
}
Real lm_diff = 0;
Real lm_max = 0;
auto it = sm_.begin();
while (it != sm_.end()) {
auto slave = it->first;
Real epsilon = (*this)[Alpha] * penalty_[slave];
AKANTU_DEBUG_ASSERT(epsilon != 0, "Penalty value cannot be zero");
// get slave point
point_type s(&position(slave));
auto master = it->second;
bool no_master = master == element_type();
// if node lies outside triangle
if (no_master || !TangentTraits<dim>::projects(s, master, position)) {
auto r = cp->search(&position(slave));
// try to find a new master
if (r != -1) {
it->second = master =
element_type(model_, TangentTraits<dim>::master_type, r);
}
// else remove master-slave pair from simulation
else {
master = element_type();
gaps_.erase(slave);
lambda_new.erase(slave);
++it;
continue;
}
}
assert(master.type == TangentTraits<dim>::master_type);
Distance_minimizator<dim, TangentTraits<dim>::master_type> dm(
s, master.coordinates());
vector_type xi = vector_type(dim - 1);
for (int i = 0; i < dim - 1; ++i)
xi[i] = dm.master_coordinates()[i];
point_type p = dm.point();
// compute normal
vector_type nu = master.normal();
point_type nup(static_cast<const Real *>(nu.data()));
// compute and save gap
Real gap = -(nup * (s - p));
gaps_[slave] = gap;
Real lambda_hat = multipliers_[slave] + epsilon * gap;
if (lambda_hat < 0) {
// increase iterator
++it;
// save value of lambda
lambda_new[slave] = 0;
continue;
}
Real s1 = epsilon * Heaviside(lambda_hat);
Real s2 = Macauley(lambda_hat); // max(0,lambda_hat)
Real s3 = s2 * gap;
std::vector<UInt> conn(master.numNodes() + 1); // 1 slave (not hardcoded)
conn[0] = slave;
for (UInt i = 0; i < master.numNodes(); ++i)
conn[1 + i] = master.node(i);
// evaluate shape functions at slave master coordinate
vector_type sh(master.numNodes());
InterpolationElement<TangentTraits<dim>::interpolation_type>::computeShapes(
xi, sh);
// compute vector N
vector_type N(dim * (master.numNodes() + 1));
for (UInt i = 0; i < dim; ++i) {
N[i] = nu[i];
for (UInt j = 0; j < master.numNodes(); ++j)
N[(1 + j) * dim + i] = -nu[i] * sh[j];
}
matrix_type dsh(dim - 1, master.numNodes());
InterpolationElement<TangentTraits<dim>::interpolation_type>::computeDNDS(
xi, dsh);
// obtain contribution to stiffness matrix and force vector depending on
// the dimension
auto t = TangentTraits<dim>::computeTangentAndResidual(
model_, std::make_tuple(gap, s1, s2, s3), master, sh, dsh, N);
matrix_type &kc = std::get<0>(t);
vector_type &fc = std::get<1>(t);
// assemble local components into global matrix and vector
std::vector<UInt> eq;
for (UInt i = 0; i < conn.size(); ++i)
for (UInt j = 0; j < dim; ++j)
eq.push_back(eqnum(conn[i] * dim + j));
for (UInt i = 0; i < kc.rows(); ++i) {
F[eq[i]] += fc(i);
for (UInt j = i; j < kc.columns(); ++j) {
K.addToProfile(eq[i], eq[j]);
K(eq[i], eq[j]) += kc(i, j);
}
}
// update multiplier
lambda_new[slave] = s2;
Real lm_old = multipliers_[slave];
lm_max += lm_old * lm_old;
lm_old -= s2;
lm_diff += lm_old * lm_old;
// increase iterator
++it;
}
if (lm_max < tol) {
error = sqrt(lm_diff);
return sqrt(lm_diff) < tol;
}
error = sqrt(lm_diff / lm_max);
return sqrt(lm_diff / lm_max) < tol;
}
template <typename T>
Point<2, T>
closest_point_to_triangle(const Point<2, T> &p, const Point<2, T> &a,
const Point<2, T> &b, const Point<2, T> &c) {
return Point<2, T>();
}
template <int dim>
bool ContactResolution<dim, _static, _augmented_lagrangian>::
computeTangentAndResidual(Array<Real> &solution, Array<Real> &F,
SearchBase *cp, Real &error,
Int2Type<_generalized_newton>) {
const Array<Real> &position = model_.getCurrentPosition();
// get global stiffness matrix and force vector
SparseMatrix &K = model_.getStiffnessMatrix();
const Array<Int> &eqnum =
model_.getDOFSynchronizer().getLocalDOFEquationNumbers();
static bool auto_flag = true;
if (auto_flag) {
auto_flag = false;
if (!(*this)[Automatic_penalty_parameter]) {
Real epsilon = (*this)[Epsilon];
for (auto it = sm_.begin(); it != sm_.end(); ++it)
penalty_[it->first] = epsilon;
cout << "*** INFO *** Uniform penalty parameter used for all slaves: "
<< epsilon << endl;
;
}
// else get penalty values automatically
else
getPenaltyValues();
}
// size of original system
UInt original = model_.increment->getSize() * dim;
// multiplier count
size_t kk = 0;
auto it = sm_.begin();
while (it != sm_.end()) {
auto slave = it->first;
Real epsilon = (*this)[Alpha] * penalty_[slave];
if (status_change_[slave] != 0) {
;
epsilon *= (status_change_[slave] + 1.);
}
AKANTU_DEBUG_ASSERT(epsilon != 0, "Penalty value cannot be zero");
// get slave point
point_type s(&position(slave));
auto master = it->second;
bool no_master = master == element_type();
static std::map<UInt, bool> excluded;
// if node lies outside triangle
if (no_master || !TangentTraits<dim>::projects(s, master, position)) {
auto r = cp->search(&position(slave));
// try to find a new master
if (r != -1) {
it->second = master =
element_type(model_, TangentTraits<dim>::master_type, r);
no_master = false;
}
// else remove master-slave pair from simulation
else {
master = element_type();
no_master = true;
excluded[slave] = true;
}
}
Real gap;
vector_type xi;
if (!no_master) {
assert(master.type == TangentTraits<dim>::master_type);
auto tuple = TangentTraits<dim>::compute_projection(s, master);
point_type &p = std::get<0>(tuple);
xi = std::get<1>(tuple);
// compute normal
vector_type nu = master.normal();
point_type nup(static_cast<const Real *>(nu.data()));
// Real old_gap = gaps_[slave];
// compute and save gap
gap = -(nup * (s - p));
gaps_[slave] = gap;
// track status
// if node in contact
if (contact_status_[slave]) {
if (gap < -1.e-10) {
contact_status_[slave] = false;
++status_change_[slave];
// cout<<"["<<status_change_[slave]<<"] changing to
// non-contact status for node "<<slave<<". Gap from "<<old_gap<<" to
// "<<gap<<endl;
}
} else {
if (gap >= -1.e-10) {
contact_status_[slave] = true;
++status_change_[slave];
// cout<<"["<<status_change_[slave]<<"] changing to contact
// status for node "<<slave<<". Gap from "<<old_gap<<" to
// "<<gap<<endl;
}
}
}
Real lambda_hat = multipliers_[slave] + epsilon * gap;
// no contact
if (lambda_hat < 0 || excluded[slave]) {
size_t ii = original + kk;
// add contribution to stiffness matrix and residual vector
F[ii] = multipliers_[slave] / epsilon;
K.addToProfile(ii, ii);
K(ii, ii) += -1 / epsilon;
}
// contact
else {
Real s1 = epsilon * Heaviside(lambda_hat);
Real s2 = Macauley(lambda_hat); // max(0,lambda_hat)
Real s3 = s2 * gap;
std::vector<UInt> conn(master.numNodes() + 1); // 1 slave (not hardcoded)
conn[0] = slave;
for (UInt i = 0; i < master.numNodes(); ++i)
conn[1 + i] = master.node(i);
// evaluate shape functions at slave master coordinate
vector_type nu = master.normal();
vector_type sh(master.numNodes());
InterpolationElement<
TangentTraits<dim>::interpolation_type>::computeShapes(xi, sh);
// compute vector N
vector_type N(dim * (master.numNodes() + 1));
for (UInt i = 0; i < dim; ++i) {
N[i] = nu[i];
for (UInt j = 0; j < master.numNodes(); ++j)
N[(1 + j) * dim + i] = -nu[i] * sh[j];
}
matrix_type dsh(dim - 1, master.numNodes());
InterpolationElement<TangentTraits<dim>::interpolation_type>::computeDNDS(
xi, dsh);
// obtain contribution to stiffness matrix and force vector depending on
// the dimension
auto t = TangentTraits<dim>::computeTangentAndResidual(
model_, std::make_tuple(gap, s1, s2, s3), master, sh, dsh, N);
matrix_type &kc = std::get<0>(t);
vector_type &fc = std::get<1>(t);
Array<bool> &boundary = model_.getBlockedDOFs();
// assemble local components into global matrix and vector not taking into
// account fixed dofs
std::vector<UInt> eq(conn.size() * dim);
std::vector<bool> fixed(conn.size() * dim, false);
for (UInt i = 0; i < conn.size(); ++i)
for (UInt j = 0; j < dim; ++j) {
eq.at(i *dim + j) = eqnum(conn[i] * dim + j);
fixed.at(i *dim + j) = boundary(conn[i], j);
}
for (UInt i = 0; i < kc.rows(); ++i) {
// if dof is blocked, don't add terms
if (fixed.at(i))
continue;
F[eq[i]] += fc(i);
for (UInt j = i; j < kc.columns(); ++j) {
K.addToProfile(eq[i], eq[j]);
K(eq[i], eq[j]) += kc(i, j);
}
}
// terms corresponding to lagrangian multiplier contribution
size_t ii = original + kk;
// assemble contribution to force vector
F[ii] = -gap;
// assemble contribution to stiffness matrix (only upper-triangular)
for (UInt i = 0; i < N.size(); ++i) {
K.addToProfile(eq[i], ii);
K(eq[i], ii) -= N[i];
}
}
// increment multiplier counter
++kk;
// increase iterator
++it;
}
return true;
}
template <int Dim>
std::ostream &operator<<(
std::ostream &os,
const ContactResolution<Dim, _static, _augmented_lagrangian> &cr) {
typedef typename ContactResolution<
Dim, _static, _augmented_lagrangian>::element_type element_type;
os << "Augmented-Lagrangian resolution type. Parameters:" << endl;
if (cr[Automatic_penalty_parameter])
cout << "\tpenalty = auto" << endl;
else
cout << "\tpenalty = " << cr[Epsilon] << endl;
cout << "\talpha = " << cr[Alpha] << endl;
cout << "\tutol = " << cr[Multiplier_tol] << endl;
cout << "\tntol = " << cr[Newton_tol] << endl;
cout << "\tusteps = " << cr[Multiplier_max_steps] << endl;
cout << "\tnsteps = " << cr[Newton_max_steps] << endl;
cout << "\tverbose = " << cr[Verbose] << endl;
cout << "\n Slave nodes: ";
for (auto it = cr.sm_.begin(); it != cr.sm_.end(); ++it)
os << it->first << " ";
os << endl;
// loop over pairs
cout << "\n Slave master pairs" << endl;
for (auto it = cr.sm_.begin(); it != cr.sm_.end(); ++it) {
auto slave = it->first;
auto master = it->second;
os << "\tslave: " << slave << ", Master: ";
if (master == element_type())
os << "none" << endl;
else
os << master << endl;
}
return os;
}
template std::ostream &operator<<(
std::ostream &,
const ContactResolution<2, _static, _augmented_lagrangian> &);
template std::ostream &operator<<(
std::ostream &,
const ContactResolution<3, _static, _augmented_lagrangian> &);
template class ContactResolution<2, _static, _augmented_lagrangian>;
template class ContactResolution<3, _static, _augmented_lagrangian>;
__END_AKANTU__
diff --git a/src/contact/resolution/resolution_augmented_lagrangian.hh b/src/contact/resolution/resolution_augmented_lagrangian.hh
index a00b182b4..3957937a6 100644
--- a/src/contact/resolution/resolution_augmented_lagrangian.hh
+++ b/src/contact/resolution/resolution_augmented_lagrangian.hh
@@ -1,154 +1,154 @@
/**
* @file resolution_augmented_lagrangian.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact resolution classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_RESOLUTION_AUGMENTED_LAGRANGIAN_HH__
#define __AKANTU_RESOLUTION_AUGMENTED_LAGRANGIAN_HH__
#include <map>
#include "search.hh"
#include "aka_common.hh"
#include "contact_common.hh"
#include "aka_array.hh"
#include "dumpable_inline_impl.hh"
//#include "dumper_iohelper_tmpl.hh"
#include "solid_mechanics_model_element.hh"
#include "aka_optimize.hh"
#include "parsable.hh"
#define __LOC__ \
std::cout << "File " << __FILE__ << ", line " << __LINE__ << std::endl;
__BEGIN_AKANTU__
template <int Dim>
class ContactResolution<Dim, _static,
_augmented_lagrangian> : public ContactParameters,
public Parsable {
typedef SolidMechanicsModel model_type;
typedef ModelElement<model_type> element_type;
typedef std::map<UInt, element_type> slave_master_map;
typedef std::map<UInt, Real> real_map;
typedef typename real_map::iterator real_iterator;
typedef std::map<UInt, Real> gap_map;
typedef Point<Dim> point_type;
typedef array::Array<1, Real> vector_type;
typedef array::Array<2, Real> matrix_type;
model_type &model_;
slave_master_map sm_;
real_map areas_, gaps_;
real_map multipliers_, penalty_;
size_t uiter_, niter_;
Array<Real> multiplier_dumper_, pressure_dumper_;
std::map<UInt, bool> contact_status_;
std::map<UInt, int> status_change_;
protected:
//! Initialize function that's called after the derived Contact's constructor
virtual void initialize();
public:
//! Parameter constructor
ContactResolution(model_type &m);
//! Add slave
void addSlave(UInt s) { sm_[s] = element_type(); }
//! Add slave-master pair
void addPair(UInt s, element_type el) { sm_[s] = el; }
//! Add area to a slave node
void addArea(UInt n, Real a) {
if (a != 0.)
areas_[n] = a;
}
//! Implementation of the contact step
template <ContactImplementationMethod i>
void solveContactStep(SearchBase *sp) {
solveContactStepImpl(sp, Int2Type<i>());
}
//! Get contact force (sum of Lagrange multipliers)
Real getForce() {
Real f = 0.;
for (auto v : multipliers_)
f += v.second;
return f;
}
//! Get maximum value of contact pressure
Real getMaxPressure() {
Real p = 0.;
for (auto v : multipliers_) {
auto slave = v.first;
auto it = areas_.find(slave);
if (it != areas_.end())
p = std::max(p, v.second / it->second); // max(p, lambda/area)
}
return p;
}
private:
//! Compute penalty parameter values for each slave node automatically
void getPenaltyValues();
//! Add stiffness matrix and force vector contributions due to contact
bool computeTangentAndResidual(real_map &lambda_new, SearchBase *cp,
Real &error, Int2Type<_uzawa>);
bool computeTangentAndResidual(Array<Real> &solution, Array<Real> &rhs,
SearchBase *cp, Real &error,
Int2Type<_generalized_newton>);
//! Implementation of the contact step using Uzawa's method
void solveContactStepImpl(SearchBase *sp, Int2Type<_uzawa>);
//! Implementation of the contact step using Uzawa's method
void solveContactStepImpl(SearchBase *sp, Int2Type<_generalized_newton>);
protected:
//! Dump of Paraview files including contact information
void dump();
//! Provide standard output of resolution object
template <int D>
friend std::ostream &operator<<(
std::ostream &os,
const ContactResolution<D, _static, _augmented_lagrangian> &);
};
__END_AKANTU__
#endif /* __AKANTU_RESOLUTION_AUGMENTED_LAGRANGIAN_HH__ */
diff --git a/src/contact/scheme.cc b/src/contact/scheme.cc
index 86bd89bf0..ab2a3ec1e 100644
--- a/src/contact/scheme.cc
+++ b/src/contact/scheme.cc
@@ -1,36 +1,37 @@
/**
* @file scheme.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jan 04 2013
+ * @date creation: Mon Jul 09 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact scheme classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "scheme.hh"
__BEGIN_AKANTU__
__END_AKANTU__
diff --git a/src/contact/scheme.hh b/src/contact/scheme.hh
index bcae584f1..8bdee7b61 100644
--- a/src/contact/scheme.hh
+++ b/src/contact/scheme.hh
@@ -1,48 +1,48 @@
/**
* @file scheme.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact scheme classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SCHEME_HH__
#define __AKANTU_SCHEME_HH__
#include "aka_common.hh"
#include "contact_common.hh"
#include "discretization.hh"
#include "friction.hh"
__BEGIN_AKANTU__
__END_AKANTU__
#endif /* __AKANTU_SCHEME_HH__ */
diff --git a/src/contact/search.cc b/src/contact/search.cc
index 5ab8032a6..bd873bee5 100644
--- a/src/contact/search.cc
+++ b/src/contact/search.cc
@@ -1,36 +1,37 @@
/**
* @file search.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jan 04 2013
+ * @date creation: Mon Jul 09 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief global contact search
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "search.hh"
__BEGIN_AKANTU__
__END_AKANTU__
diff --git a/src/contact/search.hh b/src/contact/search.hh
index e593ecaa5..eb420bc52 100644
--- a/src/contact/search.hh
+++ b/src/contact/search.hh
@@ -1,151 +1,152 @@
/**
* @file search.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Mon Sep 15 2014
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief global contact search
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SEARCH_HH__
#define __AKANTU_SEARCH_HH__
#include <iostream>
#include "aka_common.hh"
#include "solid_mechanics_model.hh"
#include "aka_point.hh"
#include "aka_geometry.hh"
__BEGIN_AKANTU__
struct SearchBase {
template <class model_type>
SearchBase(model_type & model) {
}
virtual int search(const Real *) {
static bool msg = false;
if (!msg) {
std::cout << " - Warning: calling default base searcher, type any key to continue." << std::endl;
std::cin.ignore();
msg = true;
}
return -1;
}
virtual ~SearchBase()
{
}
//! Provide standard output of contact object
friend std::ostream& operator << (std::ostream & os, const SearchBase &cr) {
os << "Search base class (no search performed)" << std::endl;
return os;
}
};
template <int dim, class model_type>
class SearchTraits;
template <class model_type>
struct SearchTraits <3, model_type> {
typedef Point <3> point_type;
typedef ModelElement <model_type> element_type;
static bool check_projection(const point_type& p, model_type& model, UInt id) {
element_type m(model, _triangle_3, id);
return point_has_projection_to_triangle(p, m.template point <3>(0), m.template point <3>(1), m.template point <3>(2));
}
};
template <class model_type>
struct SearchTraits <2, model_type> {
typedef Point <2> point_type;
typedef ModelElement <model_type> element_type;
static bool check_projection(const point_type& p, model_type& model, UInt id) {
element_type m(model, _segment_2, id);
return has_projection(p, m.template point <2>(0), m.template point <2>(1));
}
};
template <int dim>
struct MasterAssignator : public SearchBase {
typedef Point <dim> point_type;
typedef SolidMechanicsModel model_type;
std::list <std::string> surfaces_;
model_type &model_;
MasterAssignator(model_type & m) : SearchBase(m), surfaces_(), model_(m)
{
}
virtual int search(const Real *ptr) {
point_type p(ptr);
for (auto surface: surfaces_) {
ElementGroup &rs = model_.getMesh().getElementGroup(surface);
for (ElementGroup::type_iterator tit = rs.firstType(); tit != rs.lastType(); ++tit)
for (ElementGroup::const_element_iterator it = rs.element_begin(*tit);
it != rs.element_end(*tit); ++it)
if (SearchTraits <dim, model_type>::check_projection(p, model_, *it))
return *it;
}
return -1;
}
void searchSurface(const std::string& s) {
surfaces_.push_back(s);
}
//! Provide standard output of contact object
friend std::ostream& operator << (std::ostream & os, const MasterAssignator &s) {
os << "MasterAssignator search class. Search surfaces: ";
for (auto surface : s.surfaces_)
os << " " << surface;
os << std::endl;
return os;
}
};
__END_AKANTU__
#endif /* __AKANTU_SEARCH_HH__ */
diff --git a/src/contact/surface.cc b/src/contact/surface.cc
index 7d0fcd04f..06b75d82c 100644
--- a/src/contact/surface.cc
+++ b/src/contact/surface.cc
@@ -1,36 +1,37 @@
/**
* @file surface.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jan 04 2013
+ * @date creation: Mon Jul 09 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact surface classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "surface.hh"
__BEGIN_AKANTU__
__END_AKANTU__
diff --git a/src/contact/surface.hh b/src/contact/surface.hh
index dce176e0c..2515bc15c 100644
--- a/src/contact/surface.hh
+++ b/src/contact/surface.hh
@@ -1,181 +1,181 @@
/**
* @file surface.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Wed Mar 13 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact surface classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_CSURFACE_HH__
#define __AKANTU_CSURFACE_HH__
#include <set>
#include "aka_common.hh"
#include "aka_bounding_box.hh"
#include "contact_common.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
template <int d, class model_type>
BoundingBox<d> getBoundingBox(const Element& el, model_type& model) {
typedef BoundingBox<d> bbox_type;
typedef typename BoundingBox<d>::point_type point_type;
Mesh &mesh = model.getMesh();
const Array<Real> &x = model.getCurrentPosition();
// for each element, construct the bounding box
bbox_type elem_bb = bbox_type();
UInt nb_nodes = mesh.getNbNodesPerElement(el.type);
const Array<UInt> &conn = mesh.getConnectivity(el.type);
for (UInt n = 0; n<nb_nodes; ++n) {
UInt node = conn(el.element, n);
elem_bb += point_type(&x(node));
}
return elem_bb;
}
//! This class represents a contact element surface
template <int d>
class CSurface {
struct Element_set_comparator {
bool operator()(const Element& el1, const Element& el2) const
{ return el1.element < el2.element; }
};
public:
// type definitions
typedef BoundingBox<d> bbox_type;
typedef typename bbox_type::point_type point_type;
typedef SolidMechanicsModel model_type;
typedef std::set<Element, Element_set_comparator> element_container;
typedef typename element_container::const_iterator element_iterator;
typedef std::set<UInt> node_container;
typedef typename node_container::const_iterator node_iterator;
private:
element_container elements_; //!< Surface sides
node_container nodes_; //!< Surface nodes
bbox_type bbox_; //!< Bounding box
const model_type &model_; //!< Reference to model
public:
CSurface(const model_type &model) : elements_(), bbox_(), model_(model) {}
CSurface& operator=(const CSurface& cs) {
if (this != &cs) {
new (this) CSurface(cs);
}
return *this;
}
void update_bounding_box() {
bbox_ = bbox_type();
const Array<Real> &x = model_.getCurrentPosition();
// loop over all nodes to find out bounding box
for (node_iterator it = nodes_.begin(); it != nodes_.end(); ++it)
bbox_ += point_type(&x(*it));
}
bbox_type const& bounding_box() const
{ return bbox_; }
//! Add an element to the surface
void add_element(ElementType type, UInt id)
{ elements_.insert(Element(type, id)); }
void add_node(UInt n)
{ nodes_.insert(n); }
//! Return the number of elements in the surface
UInt size() const
{ return elements_.size(); }
void intersects(const bbox_type& bb, std::set<const Element*>& intersected) const {
// loop over elements
for (element_iterator it = elements_.begin(); it != elements_.end(); ++it) {
// for each element, construct the bounding box
bbox_type elem_bb = getBoundingBox<d>(*it, model_);
// check for bounding box intersection
if (bb & elem_bb)
intersected.insert(&*it);
} // loop over elements
}
bool in_surface(UInt np, const Element* sp) const {
element_iterator elit = elements_.find(*sp);
if (elit == elements_.end())
return false;
node_iterator nit = nodes_.find(np);
if (nit == nodes_.end())
return false;
return true;
}
//! Enable std output
friend std::ostream& operator<<(std::ostream& os, const CSurface& s) {
os<<" Contact surface: "<<endl;
os<<" bounding box: "<<s.bounding_box()<<endl;
os<<" "<< s.elements_.size()<<" surface elements:"<<endl;
for (typename CSurface::element_iterator it = s.elements_.begin(); it != s.elements_.end(); ++it)
os<<" "<<it->element;
os<<"\n "<<s.nodes_.size()<<" surface nodes:"<<endl;
for (typename CSurface::node_iterator it = s.nodes_.begin(); it != s.nodes_.end(); ++it)
os<<" "<<*it;
return os<<endl;
}
};
__END_AKANTU__
#endif /* __AKANTU_CSURFACE_HH__ */
diff --git a/src/contact/zone.cc b/src/contact/zone.cc
index e64d0244c..e0185b182 100644
--- a/src/contact/zone.cc
+++ b/src/contact/zone.cc
@@ -1,37 +1,38 @@
/**
* @file zone.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
- * @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jan 04 2013
+ * @date creation: Mon Jul 09 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact zone classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "zone.hh"
__BEGIN_AKANTU__
__END_AKANTU__
diff --git a/src/contact/zone.hh b/src/contact/zone.hh
index a40f237cd..52965c1f8 100644
--- a/src/contact/zone.hh
+++ b/src/contact/zone.hh
@@ -1,436 +1,436 @@
/**
* @file zone.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Tue May 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief contact zone classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_CZONE_HH__
#define __AKANTU_CZONE_HH__
#include <unordered_set>
#include "aka_common.hh"
#include "surface.hh"
__BEGIN_AKANTU__
//! This class represents a contact element surface
template <int d>
class CZone {
public:
typedef CSurface<d> contact_surface;
typedef typename std::list<const contact_surface*> surface_list;
typedef typename surface_list::const_iterator surface_iterator;
typedef typename CSurface<d>::point_type point_type;
typedef typename CSurface<d>::bbox_type bbox_type;
// typedef std::set<UInt> node_set;
typedef std::unordered_set<UInt> node_set;
typedef typename node_set::iterator node_iterator;
typedef typename node_set::const_iterator const_node_iterator;
typedef std::map<int, node_set> bucket_container;
typedef typename bucket_container::iterator bucket_iterator;
typedef typename bucket_container::const_iterator const_bucket_iterator;
typedef std::set<const Element*> element_container;
typedef typename element_container::const_iterator element_iterator;
// typedef std::map<UInt, element_container> node_element_map;
// typedef typename node_element_map::iterator node_element_iterator;
typedef std::map<int, element_container> elementmap;
typedef typename elementmap::iterator elementmap_iterator;
typedef typename elementmap::const_iterator const_elementmap_iterator;
private:
SolidMechanicsModel& model_;
bbox_type bbox_;
Real delta_[d]; //!< grid size length
int size_[d]; //!< grid dimensions, number of buckets in each dimension
int index_[d]; //!< indexes to convert to 1D equivalent array
bucket_container buckets_;
elementmap elements_;
// node_element_map node_element_map_;
surface_list surfaces_;
public:
CZone() {}
// clear memory
void clear() {
buckets_.clear();
// node_element_map_.clear();
}
typename bucket_container::size_type buckets_size() const
{ return buckets_.size(); }
bucket_iterator buckets_begin()
{ return buckets_.begin(); }
bucket_iterator buckets_end()
{ return buckets_.end(); }
const_bucket_iterator buckets_begin() const
{ return buckets_.begin(); }
const_bucket_iterator buckets_end() const
{ return buckets_.end(); }
void erase_bucket(bucket_iterator bit)
{ buckets_.erase(bit); }
CZone(SolidMechanicsModel& model,
const bbox_type& bb,
const element_container& elems,
const contact_surface& s1,
const contact_surface& s2)
: model_(model), bbox_(bb), delta_(), size_(), index_() {
assert(!elems.empty());
surfaces_.push_back(&s1);
surfaces_.push_back(&s2);
// tolerance
Real epsilon = 2*std::numeric_limits<Real>::epsilon();
// loop over elements to get bucket increments
typedef typename element_container::const_iterator element_iterator;
for (element_iterator it = elems.begin(); it != elems.end(); ++it) {
// get side bounding box
bbox_type bb = getBoundingBox<d>(**it, model_);
// process box to modify delta array
const point_type &m = bb.min();
const point_type &M = bb.max();
for (int i=0; i<d; ++i)
delta_[i] = std::max(delta_[i], (M[i] - m[i])/3. + epsilon);
}
// get the number of buckets in each direction
const point_type& m = bbox_.min();
const point_type& M = bbox_.max();
for (int i=0; i<d; ++i) {
assert(delta_[i] != 0.);
size_[i] = static_cast<int>((M[i] - m[i]) / delta_[i])+1;
}
// get indexes to convert multi-dimensional indexes to a 1D array
index_[0] = 1;
for (int i=1; i<d; ++i)
index_[i] = index_[i-1]*size_[i-1];
// add elements to buckets
add_elements(elems);
std::set<UInt> nodes_inside;
Mesh &mesh = model.getMesh();
const Array<Real> &x = model.getCurrentPosition();
// loop over elements
for (element_iterator it = elems.begin(); it != elems.end(); ++it) {
UInt nb_nodes = mesh.getNbNodesPerElement((*it)->type);
const Array<UInt> &conn = mesh.getConnectivity((*it)->type);
// loop over nodes
for (UInt n = 0; n<nb_nodes; ++n) {
UInt node = conn((*it)->element, n);
point_type node_coord = point_type(&x(node));
// if node is within bounding box
if (bbox_ & node_coord) {
nodes_inside.insert(node);
// compute index into one-dimensional array
int coord[d];
for (int i=0; i<d; ++i)
coord[i] = static_cast<int>((node_coord[i] - m[i])/delta_[i]);
int idx = compute_index(coord);
// add node to bucket
buckets_[idx].insert(node);
// // add side to map
// node_element_map_[node].insert(*it);
} // node within bounding box
} // loop over nodes
} // loop over elements
// check nodes
std::set<UInt> node_check;
for (bucket_iterator it = buckets_.begin(); it != buckets_.end(); ++it)
for (node_iterator nit = it->second.begin(); nit != it->second.end(); ++nit)
node_check.insert(*nit);
cout<<"*** INFO *** Node check after creating buckets passed: "<<(node_check.size() == nodes_inside.size())<<endl;
assert(node_check.size() == nodes_inside.size());
#ifdef DEBUG_CONTACT
cout<<"*** INFO *** A total of "<<nodes_inside.size()<<" nodes lie inside the contact zone."<<endl;
cout<<"*** INFO *** A total of "<<buckets_.size()<<" node buckets were created."<<endl;
#endif
}
int compute_index(int *array) const {
int idx = 0;
for (int i=0; i<d; ++i)
idx += index_[i]*array[i];
return idx;
}
void decompute_index(int idx, int *array, Int2Type<2>) const {
array[0] = idx % index_[1];
array[1] = idx / index_[1];
}
void decompute_index(int idx, int *array, Int2Type<3>) const {
array[0] = (idx % (index_[2])) % index_[1];
array[1] = (idx % (index_[2])) / index_[1];
array[2] = idx / index_[2];
}
void add_elements(const element_container& s) {
const point_type& bbm = bbox_.min();
// loop over elements
for (element_iterator it = s.begin(); it != s.end(); ++it) {
bbox_type elbb = getBoundingBox<d>(**it, model_);
const point_type& elmin = elbb.min();
const point_type& elmax = elbb.max();
int min[d], max[d];
for (int i=0; i<d; ++i) {
min[i] = std::max(0, static_cast<int>((elmin[i] - bbm[i])/delta_[i]));
max[i] = std::min(size_[i], static_cast<int>((elmax[i] - bbm[i])/delta_[i]) +1);
}
add_element(*it, min, max, Int2Type<d>());
} // loop over elements
}
void add_element(const Element* el, int *min, int*max, Int2Type<2>) {
for (int i=min[0]; i<max[0]; ++i) {
for (int j=min[1]; j<max[1]; ++j) {
int idxarray[d] = {i,j};
int idx = compute_index(idxarray);
elements_[idx].insert(el);
}
}
}
void add_element(const Element* el, int *min, int*max, Int2Type<3>) {
for (int i=min[0]; i<max[0]; ++i) {
for (int j=min[1]; j<max[1]; ++j) {
for (int k=min[2]; k<max[2]; ++k) {
int idxarray[d] = {i,j,k};
int idx = compute_index(idxarray);
elements_[idx].insert(el);
}
}
}
}
element_container contiguous(int bucket) {
element_container elements;
collect(elements, bucket, Int2Type<d>());
return elements;
}
bool in_surface(UInt np, const Element* sp) {
for (surface_iterator it = surfaces_.begin(); it != surfaces_.end(); ++it) {
const contact_surface& s = **it;
if (s.in_surface(np, sp))
return true;
}
return false;
}
bool in_element(UInt np, const Element* sp) {
// loop over nodes of side
Mesh& mesh = model_.getMesh();
UInt nb_nodes = mesh.getNbNodesPerElement(sp->type);
const Array<UInt> &conn = mesh.getConnectivity(sp->type);
// loop over nodes
for (UInt n = 0; n<nb_nodes; ++n) {
UInt node = conn(sp->element, n);
if (node == np)
return true;
}
return false;
}
void set_union(int bucket, element_container& elements) const {
// check if bucket exists
const_elementmap_iterator it = elements_.find(bucket);
// if bucket is not found, return since there are no elements to add
if (it == elements_.end())
return;
// otherwise add elements
for (element_iterator sit = it->second.begin(); sit != it->second.end(); ++sit)
elements.insert(*sit);
}
template <class container_type>
void collect(container_type &c, int idx, Int2Type<2>) const {
const int &m = size_[0];
const int &n = size_[1];
int coord[d];
decompute_index(idx, coord, Int2Type<2>());
for (int i=coord[0]-1; i<=coord[0]+1; ++i)
if (i >=0 && i<m)
for (int j=coord[1]-1; j<=coord[1]+1; ++j)
if (j >=0 && j<n) {
int cont[d] = { i, j};
set_union(compute_index(cont), c);
}
}
template <class container_type>
void collect(container_type &c, int idx, Int2Type<3>) const {
const int &m = size_[0];
const int &n = size_[1];
const int &p = size_[2];
int coord[d];
decompute_index(idx, coord, Int2Type<3>());
for (int i=coord[0]-1; i<=coord[0]+1; ++i)
if (i >=0 && i<m)
for (int j=coord[1]-1; j<=coord[1]+1; ++j)
if (j >=0 && j<n)
for (int k=coord[2]-1; k<=coord[2]+1; ++k)
if (k >=0 && k<p) {
int cont[d] = { i, j, k};
set_union(compute_index(cont), c);
}
}
//! Enable std output
friend std::ostream& operator<<(std::ostream& os, const CZone& cz) {
Mesh& mesh = cz.model_.getMesh();
const Array<Real> &x = cz.model_.getCurrentPosition();
int coord[d];
os<<" Contact zone: "<<endl;
os<<" origin: "<<cz.bbox_.min()<<endl;
os<<" bounding box: "<<cz.bbox_<<endl;
os<<" delta: (";
for (int i=0; i<d-1; ++i)
os<<cz.delta_[i]<<",";
os<<cz.delta_[d-1]<<")"<<endl;
os<<" size: (";
for (int i=0; i<d-1; ++i)
os<<cz.size_[i]<<",";
os<<cz.size_[d-1]<<")"<<endl;
os<<" number of node buckets: "<<cz.buckets_.size()<<endl;
std::set<UInt> nodes;
for (const_bucket_iterator it = cz.buckets_.begin(); it != cz.buckets_.end(); ++it) {
os<<" node bucket "<<it->first;
cz.decompute_index(it->first, coord, Int2Type<d>());
os<<" ("<<coord[0];
for (int i=1; i<d; ++i)
os<<","<<coord[i];
os<<") contains "<<it->second.size()<<" nodes:";
for (const_node_iterator nit = it->second.begin(); nit != it->second.end(); ++nit) {
os<<" "<<*nit<<" ("<<point_type(&x(*nit))<<")";
nodes.insert(*nit);
}
os<<endl;
}
os<<" there are a total of "<<nodes.size()<<" nodes in the node buckets."<<endl;
os<<" number of element buckets: "<<cz.elements_.size()<<endl;
for (const_elementmap_iterator it = cz.elements_.begin(); it != cz.elements_.end(); ++it) {
os<<" element bucket "<<it->first;
cz.decompute_index(it->first, coord, Int2Type<d>());
os<<" ("<<coord[0];
for (int i=1; i<d; ++i)
os<<","<<coord[i];
os<<") contains "<<it->second.size()<<" elements:"<<endl;
for (element_iterator sit = it->second.begin(); sit != it->second.end(); ++sit) {
os<<"\t\t"<<**sit;
UInt nb_nodes = mesh.getNbNodesPerElement((*sit)->type);
const Array<UInt> &conn = mesh.getConnectivity((*sit)->type);
os<<", nodes:";
// loop over nodes
for (UInt n = 0; n<nb_nodes; ++n)
os<<" "<<conn((*sit)->element, n)<<" ("<<
point_type(&x(conn((*sit)->element, n)))<<")";
os<<endl;
}
}
return os;
}
};
__END_AKANTU__
#endif /* __AKANTU_CZONE_HH__ */
diff --git a/src/fe_engine/cohesive_element.cc b/src/fe_engine/cohesive_element.cc
index f02c0cbfb..36d207212 100644
--- a/src/fe_engine/cohesive_element.cc
+++ b/src/fe_engine/cohesive_element.cc
@@ -1,148 +1,150 @@
/**
* @file cohesive_element.cc
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri Feb 03 2012
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Sun Sep 26 2010
+ * @date last modification: Mon Sep 14 2015
*
* @brief CohesiveElement implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "cohesive_element.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_cohesive_2d_4>::spatial_dimension = 2;
template<> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_nodes_per_element = 4;
template<> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_facets[] = { 2 };
template<> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_nodes_per_facet[] = { 2 };
template<> UInt GeometricalElement<_gt_cohesive_2d_4>::facet_connectivity_vect[] = {0, 2,
1, 3};
template<> UInt * GeometricalElement<_gt_cohesive_2d_4>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> ElementType ElementClass<_cohesive_2d_4>::facet_type[] = { _segment_2 };
template<> ElementType ElementClass<_cohesive_2d_4>::p1_type = _cohesive_2d_4;
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_cohesive_2d_6>::spatial_dimension = 2;
template<> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_nodes_per_element = 6;
template<> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_facets[] = { 2 };
template<> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_nodes_per_facet[] = { 3 };
template<> UInt GeometricalElement<_gt_cohesive_2d_6>::facet_connectivity_vect[] = {0, 3,
1, 4,
2, 5};
template<> UInt * GeometricalElement<_gt_cohesive_2d_6>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> ElementType ElementClass<_cohesive_2d_6>::facet_type[] = { _segment_3 };
template<> ElementType ElementClass<_cohesive_2d_6>::p1_type = _cohesive_2d_4;
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_cohesive_1d_2>::spatial_dimension = 1;
template<> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_nodes_per_element = 2;
template<> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_facets[] = { 2 };
template<> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_nodes_per_facet[] = { 1 };
template<> UInt GeometricalElement<_gt_cohesive_1d_2>::facet_connectivity_vect[] = {0,
1};
template<> UInt * GeometricalElement<_gt_cohesive_1d_2>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> ElementType ElementClass<_cohesive_1d_2>::facet_type[] = { _point_1 };
template<> ElementType ElementClass<_cohesive_1d_2>::p1_type = _cohesive_1d_2;
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_cohesive_3d_6>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_nodes_per_element = 6;
template<> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_facets[] = { 2 };
template<> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_nodes_per_facet[] = { 3 };
template<> UInt GeometricalElement<_gt_cohesive_3d_6>::facet_connectivity_vect[] = {0, 3,
1, 4,
2, 5};
template<> UInt * GeometricalElement<_gt_cohesive_3d_6>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> ElementType ElementClass<_cohesive_3d_6>::facet_type[] = { _triangle_3 };
template<> ElementType ElementClass<_cohesive_3d_6>::p1_type = _cohesive_3d_6;
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_cohesive_3d_12>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_nodes_per_element = 12;
template<> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_facets[] = { 2 };
template<> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_nodes_per_facet[] = { 6 };
template<> UInt GeometricalElement<_gt_cohesive_3d_12>::facet_connectivity_vect[] = {0, 6,
1, 7,
2, 8,
3, 9,
4, 10,
5, 11};
template<> UInt * GeometricalElement<_gt_cohesive_3d_12>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> ElementType ElementClass<_cohesive_3d_12>::facet_type[] = { _triangle_6 };
template<> ElementType ElementClass<_cohesive_3d_12>::p1_type = _cohesive_3d_6;
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_cohesive_3d_8>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_nodes_per_element = 8;
template<> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_facets[] = { 2 };
template<> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_nodes_per_facet[] = { 4 };
template<> UInt GeometricalElement<_gt_cohesive_3d_8>::facet_connectivity_vect[] = {0, 4,
1, 5,
2, 6,
3, 7};
template<> UInt * GeometricalElement<_gt_cohesive_3d_8>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> ElementType ElementClass<_cohesive_3d_8>::facet_type[] = { _quadrangle_4 };
template<> ElementType ElementClass<_cohesive_3d_8>::p1_type = _cohesive_3d_8;
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_cohesive_3d_16>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_nodes_per_element = 16;
template<> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_facets[] = { 2 };
template<> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_nodes_per_facet[] = { 8 };
template<> UInt GeometricalElement<_gt_cohesive_3d_16>::facet_connectivity_vect[] = {0, 8,
1, 9,
2, 10,
3, 11,
4, 12,
5, 13,
6, 14,
7, 15};
template<> UInt * GeometricalElement<_gt_cohesive_3d_16>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> ElementType ElementClass<_cohesive_3d_16>::facet_type[] = { _quadrangle_8 };
template<> ElementType ElementClass<_cohesive_3d_16>::p1_type = _cohesive_3d_8;
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/fe_engine/cohesive_element.hh b/src/fe_engine/cohesive_element.hh
index 39bc5086b..1219a2319 100644
--- a/src/fe_engine/cohesive_element.hh
+++ b/src/fe_engine/cohesive_element.hh
@@ -1,72 +1,74 @@
/**
* @file cohesive_element.hh
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri Feb 03 2012
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 22 2015
*
* @brief Generates the cohesive element structres (defined in element_class.hh)
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "element_class.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COHESIVE_ELEMENT_HH__
#define __AKANTU_COHESIVE_ELEMENT_HH__
__BEGIN_AKANTU__
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_2d_4, _gt_cohesive_2d_4, _itp_lagrange_segment_2,
_ek_cohesive, 2,
_git_segment, 1);
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_2d_6, _gt_cohesive_2d_6, _itp_lagrange_segment_3,
_ek_cohesive, 2,
_git_segment, 2);
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_1d_2, _gt_cohesive_1d_2, _itp_lagrange_point_1,
_ek_cohesive, 1,
_git_point, 1);
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_3d_6, _gt_cohesive_3d_6, _itp_lagrange_triangle_3,
_ek_cohesive, 3,
_git_triangle, 1);
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_3d_12, _gt_cohesive_3d_12, _itp_lagrange_triangle_6,
_ek_cohesive, 3,
_git_triangle, 2);
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_3d_8, _gt_cohesive_3d_8, _itp_lagrange_quadrangle_4,
_ek_cohesive, 3,
_git_segment, 1);
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_3d_16, _gt_cohesive_3d_16, _itp_serendip_quadrangle_8,
_ek_cohesive, 3,
_git_segment, 2);
__END_AKANTU__
#endif /* __AKANTU_COHESIVE_ELEMENT_HH__ */
diff --git a/src/fe_engine/element.hh b/src/fe_engine/element.hh
index 252a83282..a2e35603e 100644
--- a/src/fe_engine/element.hh
+++ b/src/fe_engine/element.hh
@@ -1,127 +1,127 @@
/**
* @file element.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Sat Jul 11 2015
*
* @brief Element helper class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_ELEMENT_HH__
#define __AKANTU_ELEMENT_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Element */
/* -------------------------------------------------------------------------- */
class Element;
extern const Element ElementNull;
class Element {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
explicit Element(ElementType type = _not_defined, UInt element = 0,
GhostType ghost_type = _not_ghost, ElementKind kind = _ek_regular) :
type(type), element(element),
ghost_type(ghost_type), kind(kind) {};
Element(const Element & element) {
this->type = element.type;
this->element = element.element;
this->ghost_type = element.ghost_type;
this->kind = element.kind;
}
virtual ~Element() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline bool operator==(const Element & elem) const {
return ((element == elem.element)
&& (type == elem.type)
&& (ghost_type == elem.ghost_type)
&& (kind == elem.kind));
}
inline bool operator!=(const Element & elem) const {
return ((element != elem.element)
|| (type != elem.type)
|| (ghost_type != elem.ghost_type)
|| (kind != elem.kind));
}
bool operator<(const Element& rhs) const {
bool res = (rhs == ElementNull) || ((this->kind < rhs.kind) ||
((this->kind == rhs.kind) &&
((this->ghost_type < rhs.ghost_type) ||
((this->ghost_type == rhs.ghost_type) &&
((this->type < rhs.type) ||
((this->type == rhs.type) &&
(this->element < rhs.element)))))));
return res;
}
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
const ElementType & getType(){return type;}
const UInt & getIndex(){return element;};
const GhostType & getGhostType(){return ghost_type;}
const ElementKind & getElementKind(){return kind;}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
ElementType type;
UInt element;
GhostType ghost_type;
ElementKind kind;
};
struct CompElementLess {
bool operator() (const Element& lhs, const Element& rhs) const {
return lhs < rhs;
}
};
__END_AKANTU__
#endif /* __AKANTU_ELEMENT_HH__ */
diff --git a/src/fe_engine/element_class.cc b/src/fe_engine/element_class.cc
index c31cf9e7e..379148d0f 100644
--- a/src/fe_engine/element_class.cc
+++ b/src/fe_engine/element_class.cc
@@ -1,84 +1,86 @@
/**
* @file element_class.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Peter Spijker <peter.spijker@epfl.ch>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Peter Spijker <peter.spijker@epfl.ch>
*
* @date creation: Tue Jul 20 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Thu Jul 16 2015
*
* @brief Common part of element_classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "element_class.hh"
/* -------------------------------------------------------------------------- */
using std::sqrt;
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_not_defined>::p1_type = _not_defined;
template<> ElementType ElementClass<_not_defined>::facet_type[] = {_not_defined};
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_point_1>::p1_type = _point_1;
template<> ElementType ElementClass<_point_1>::facet_type[] = {_point_1};
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_segment_2>::p1_type = _segment_2;
template<> ElementType ElementClass<_segment_2>::facet_type[] = {_point_1};
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_segment_3>::p1_type = _segment_2;
template<> ElementType ElementClass<_segment_3>::facet_type[] = {_point_1};
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_triangle_3>::p1_type = _triangle_3;
template<> ElementType ElementClass<_triangle_3>::facet_type[] = {_segment_2};
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_triangle_6>::p1_type = _triangle_3;
template<> ElementType ElementClass<_triangle_6>::facet_type[] = {_segment_3};
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_tetrahedron_4>::p1_type = _tetrahedron_4;
template<> ElementType ElementClass<_tetrahedron_4>::facet_type[]= {_triangle_3};
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_tetrahedron_10>::p1_type = _tetrahedron_4;
template<> ElementType ElementClass<_tetrahedron_10>::facet_type[] = {_triangle_6};
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_quadrangle_4>::p1_type = _quadrangle_4;
template<> ElementType ElementClass<_quadrangle_4>::facet_type[] = {_segment_2};
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_quadrangle_8>::p1_type = _quadrangle_4;
template<> ElementType ElementClass<_quadrangle_8>::facet_type[] = { _segment_3 };
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_hexahedron_8>::p1_type = _hexahedron_8;
template<> ElementType ElementClass<_hexahedron_8>::facet_type[] = { _quadrangle_4 };
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_hexahedron_20>::p1_type = _hexahedron_8;
template<> ElementType ElementClass<_hexahedron_20>::facet_type[] = { _quadrangle_8 };
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_pentahedron_6>::p1_type = _pentahedron_6;
template<> ElementType ElementClass<_pentahedron_6>::facet_type[] = { _triangle_3, _quadrangle_4 };
/* -------------------------------------------------------------------------- */
template<> ElementType ElementClass<_pentahedron_15>::p1_type = _pentahedron_6;
template<> ElementType ElementClass<_pentahedron_15>::facet_type[] = { _triangle_6, _quadrangle_8 };
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/fe_engine/element_class.hh b/src/fe_engine/element_class.hh
index 106f81ffe..e89f78614 100644
--- a/src/fe_engine/element_class.hh
+++ b/src/fe_engine/element_class.hh
@@ -1,370 +1,372 @@
/**
* @file element_class.hh
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Fri Jul 04 2014
+ * @date last modification: Thu Oct 22 2015
*
* @brief Declaration of the ElementClass main class and the
* Integration and Interpolation elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_types.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_CLASS_HH__
#define __AKANTU_ELEMENT_CLASS_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/// default element class structure
template<ElementType element_type>
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<elem_type> { \
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<GeometricalType geometrical_type>
struct GeometricalShape {
static const GeometricalShapeType shape = _gst_point;
};
/// Templated GeometricalShape with function contains
template<GeometricalShapeType shape>
struct GeometricalShapeContains {
/// Check if the point (vector in 2 and 3D) at natural coordinate coor
template <class vector_type>
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<geom_type> { \
static const GeometricalShapeType shape = geom_shape; \
}
/* -------------------------------------------------------------------------- */
/// Templated GeometricalElement with function getInradius
template< GeometricalType geometrical_type,
GeometricalShapeType shape = GeometricalShape<geometrical_type>::shape >
class GeometricalElement {
public:
/// compute the in-radius
static inline Real getInradius(__attribute__((unused)) const Matrix<Real> & coord) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// true if the natural coordinates are in the element
template <class vector_type>
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<UInt> 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<InterpolationType interpolation_type>
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<itp_type> { \
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<InterpolationType interpolation_type,
InterpolationKind kind = InterpolationPorperty<interpolation_type>::kind>
class InterpolationElement {
public:
typedef InterpolationPorperty<interpolation_type> interpolation_property;
/// compute the shape values for a given set of points in natural coordinates
static inline void computeShapes(const Matrix<Real> & natural_coord,
Matrix<Real> & N);
/// compute the shape values for a given point in natural coordinates
template <class vector_type>
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<Real> & natural_coord,
Tensor3<Real> & 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 <class vector_type, class matrix_type>
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<Real> & J,
__attribute__((unused)) Real & jacobians) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// interpolate a field given (arbitrary) natural coordinates
static inline void interpolateOnNaturalCoordinates(const Vector<Real> & natural_coords,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated);
/// interpolate a field given the shape functions on the interpolation point
static inline void interpolate(const Matrix<Real> & nodal_values,
const Vector<Real> & shapes,
Vector<Real> & interpolated);
/// interpolate a field given the shape functions on the interpolations points
static inline void interpolate(const Matrix<Real> & nodal_values,
const Matrix<Real> & shapes,
Matrix<Real> & interpolated);
/// compute the gradient of a given field on the given natural coordinates
static inline void gradientOnNaturalCoordinates(const Vector<Real> & natural_coords,
const Matrix<Real> & f,
Matrix<Real> & gradient);
public:
static AKANTU_GET_MACRO_NOT_CONST(ShapeSize, InterpolationPorperty<interpolation_type>::nb_nodes_per_element, UInt);
static AKANTU_GET_MACRO_NOT_CONST(ShapeDerivativesSize, (InterpolationPorperty<interpolation_type>::nb_nodes_per_element * InterpolationPorperty<interpolation_type>::natural_space_dimension), UInt);
static AKANTU_GET_MACRO_NOT_CONST(NaturalSpaceDimension, InterpolationPorperty<interpolation_type>::natural_space_dimension, UInt);
static AKANTU_GET_MACRO_NOT_CONST(NbNodesPerInterpolationElement, InterpolationPorperty<interpolation_type>::nb_nodes_per_element, UInt);
};
/* -------------------------------------------------------------------------- */
/* Integration */
/* -------------------------------------------------------------------------- */
template<GaussIntergrationType git_class, UInt max_order>
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<ElementType type, UInt order = ElementClassProperty<type>::minimal_integration_order>
class GaussIntegrationElement {
public:
static UInt getNbQuadraturePoints();
static const Matrix<Real> getQuadraturePoints();
static const Vector<Real> getWeights();
};
/* -------------------------------------------------------------------------- */
/* ElementClass */
/* -------------------------------------------------------------------------- */
template<ElementType element_type,
ElementKind element_kind = ElementClassProperty<element_type>::element_kind>
class ElementClass :
public GeometricalElement<ElementClassProperty<element_type>::geometrical_type>,
public InterpolationElement<ElementClassProperty<element_type>::interpolation_type> {
protected:
typedef GeometricalElement<ElementClassProperty<element_type>::geometrical_type> geometrical_element;
typedef InterpolationElement<ElementClassProperty<element_type>::interpolation_type> interpolation_element;
typedef ElementClassProperty<element_type> 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<Real> & dnds,
const Matrix<Real> & node_coords,
Matrix<Real> & 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<Real> & dnds,
const Matrix<Real> & node_coords,
Tensor3<Real> & J);
/// compute the jacobians of a serie of natural coordinates
static inline void computeJacobian(const Matrix<Real> & natural_coords,
const Matrix<Real> & node_coords,
Vector<Real> & jacobians);
/// compute jacobian (or integration variable change factor) for a set of points
static inline void computeJacobian(const Tensor3<Real> & J,
Vector<Real> & jacobians);
/// compute jacobian (or integration variable change factor) for a given point
static inline void computeJacobian(const Matrix<Real> & J,
Real & jacobians);
/// compute shape derivatives (input is dxds) for a set of points
static inline void computeShapeDerivatives(const Tensor3<Real> & J,
const Tensor3<Real> & dnds,
Tensor3<Real> & shape_deriv);
/// compute shape derivatives (input is dxds) for a given point
static inline void computeShapeDerivatives(const Matrix<Real> & J,
const Matrix<Real> & dnds,
Matrix<Real> & shape_deriv);
/// compute the normal of a surface defined by the function f
static inline void computeNormalsOnNaturalCoordinates(const Matrix<Real> & coord,
Matrix<Real> & f,
Matrix<Real> & normals);
/// get natural coordinates from real coordinates
static inline void inverseMap(const Vector<Real> & real_coords,
const Matrix<Real> & node_coords,
Vector<Real> & natural_coords,
Real tolerance = 1e-8);
/// get natural coordinates from real coordinates
static inline void inverseMap(const Matrix<Real> & real_coords,
const Matrix<Real> & node_coords,
Matrix<Real> & 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<element_type>::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"
__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/fe_engine/element_class_structural.hh b/src/fe_engine/element_class_structural.hh
index 2774662d4..4c34fa05f 100644
--- a/src/fe_engine/element_class_structural.hh
+++ b/src/fe_engine/element_class_structural.hh
@@ -1,243 +1,242 @@
/**
* @file element_class_structural.hh
*
- * @author Damien Spielmann <damien.spielmann@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Damien Spielmann <damien.spielmann@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Fri Jul 04 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Thu Oct 22 2015
*
* @brief Specialization of the element classes for structural elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
-
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<InterpolationType interpolation_type>
class InterpolationElement<interpolation_type, _itk_structural> {
public:
typedef InterpolationPorperty<interpolation_type> interpolation_property;
/// compute the shape values for a given set of points in natural coordinates
static inline void computeShapes(const Matrix<Real> & natural_coord,
Matrix<Real> & N,
const Matrix<Real> & real_nodal_coord,
UInt n = 0) {
UInt nb_points = natural_coord.cols();
for (UInt p = 0; p < nb_points; ++p) {
Vector<Real> Np = N(p);
computeShapes(natural_coord(p), Np, real_nodal_coord, n);
}
}
/// compute the shape values for a given point in natural coordinates
static inline void computeShapes(const Vector<Real> & natural_coord,
Vector<Real> & N,
const Matrix<Real> & real_nodal_coord,
UInt n = 0);
/**
* 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<Real> & natural_coord,
Tensor3<Real> & dnds,
const Matrix<Real> & real_nodal_coord,
UInt n = 0) {
for (UInt i = 0; i < natural_coord.cols(); ++i) {
Matrix<Real> dnds_t = dnds(i);
computeDNDS(natural_coord(i), dnds_t, real_nodal_coord, n);
}
}
/**
* 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
*/
static inline void computeDNDS(const Vector<Real> & natural_coord,
Matrix<Real> & dnds,
const Matrix<Real> & real_nodal_coord,
UInt n = 0);
public:
static AKANTU_GET_MACRO_NOT_CONST(NbShapeFunctions, nb_shape_functions, UInt);
static AKANTU_GET_MACRO_NOT_CONST(NbShapeDerivatives, nb_shape_derivatives, UInt);
static AKANTU_GET_MACRO_NOT_CONST(ShapeSize, interpolation_property::nb_nodes_per_element, UInt);
static AKANTU_GET_MACRO_NOT_CONST(ShapeDerivativesSize, (interpolation_property::nb_nodes_per_element * interpolation_property::natural_space_dimension), UInt);
static AKANTU_GET_MACRO_NOT_CONST(NaturalSpaceDimension, interpolation_property::natural_space_dimension, UInt);
protected:
/// nb shape functions
static const UInt nb_shape_functions;
static const UInt nb_shape_derivatives;
};
/// Macro to generate the element class structures for different structural element types
/* -------------------------------------------------------------------------- */
#define AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(elem_type, \
geom_type, \
interp_type, \
parent_el_type, \
elem_kind, \
sp, \
gauss_int_type, \
min_int_order) \
template<> \
struct ElementClassProperty<elem_type> { \
static const GeometricalType geometrical_type = geom_type; \
static const InterpolationType interpolation_type = interp_type; \
static const ElementType parent_element_type = parent_el_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; \
}
/* -------------------------------------------------------------------------- */
/* ElementClass for structural elements */
/* -------------------------------------------------------------------------- */
template<ElementType element_type>
class ElementClass<element_type, _ek_structural> :
public GeometricalElement<ElementClassProperty<element_type>::geometrical_type>,
public InterpolationElement<ElementClassProperty<element_type>::interpolation_type> {
protected:
typedef GeometricalElement<ElementClassProperty<element_type>::geometrical_type> geometrical_element;
typedef InterpolationElement<ElementClassProperty<element_type>::interpolation_type> interpolation_element;
typedef ElementClass<ElementClassProperty<element_type>::parent_element_type> parent_element;
public:
/// compute shape derivatives (input is dxds) for a set of points
static inline void computeShapeDerivatives(const Matrix<Real> & natural_coord,
Tensor3<Real> & shape_deriv,
const Matrix<Real> & real_nodal_coord,
UInt n = 0) {
UInt nb_points = natural_coord.cols();
if (element_type ==_kirchhoff_shell) {
/// TO BE CONTINUED and moved in a _tmpl.hh
UInt spatial_dimension = real_nodal_coord.cols();
UInt nb_nodes = real_nodal_coord.rows();
const UInt projected_dim = natural_coord.rows();
Matrix<Real> rotation_matrix(real_nodal_coord);
Matrix<Real> rotated_nodal_coord(real_nodal_coord);
Matrix<Real> projected_nodal_coord(natural_coord);
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Matrix<Real> Pe (real_nodal_coord);
Matrix<Real> Pg (real_nodal_coord);
Matrix<Real> inv_Pg(real_nodal_coord);
/// compute matrix Pe
Pe.eye();
/// compute matrix Pg
Vector<Real> Pg_col_1(spatial_dimension);
Pg_col_1(0) = real_nodal_coord(0,1) - real_nodal_coord(0,0);
Pg_col_1(1) = real_nodal_coord(1,1) - real_nodal_coord(1,0);
Pg_col_1(2) = real_nodal_coord(2,1) - real_nodal_coord(2,0);
Vector<Real> Pg_col_2(spatial_dimension);
Pg_col_2(0) = real_nodal_coord(0,2) - real_nodal_coord(0,0);
Pg_col_2(1) = real_nodal_coord(1,2) - real_nodal_coord(1,0);
Pg_col_2(2) = real_nodal_coord(2,2) - real_nodal_coord(2,0);
Vector<Real> Pg_col_3(spatial_dimension);
Pg_col_3.crossProduct(Pg_col_1, Pg_col_2);
for (UInt i = 0; i < nb_points; ++i) {
Pg(i,0) = Pg_col_1(i);
Pg(i,1) = Pg_col_2(i);
Pg(i,2) = Pg_col_3(i);
}
/// compute inverse of Pg
inv_Pg.inverse(Pg);
/// compute rotation matrix
// rotation_matrix=Pe*inv_Pg;
rotation_matrix.eye();
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
rotated_nodal_coord.mul<false, false>(rotation_matrix, real_nodal_coord);
for (UInt i = 0; i < projected_dim ; ++i) {
for (UInt j = 0; j < nb_points; ++j) {
projected_nodal_coord(i,j) = rotated_nodal_coord(i,j);
}
}
Tensor3<Real> dnds(projected_dim, nb_nodes, natural_coord.cols());
Tensor3<Real> J (projected_dim, projected_dim, natural_coord.cols());
parent_element::computeDNDS(natural_coord, dnds);
parent_element::computeJMat(dnds, projected_nodal_coord, J);
for (UInt p = 0; p < nb_points; ++p) {
Matrix<Real> shape_deriv_p = shape_deriv(p);
interpolation_element::computeDNDS(natural_coord(p), shape_deriv_p, projected_nodal_coord, n);
Matrix<Real> dNdS = shape_deriv_p;
Matrix<Real> inv_J(projected_dim, projected_dim);
inv_J.inverse(J(p));
shape_deriv_p.mul<false, false>(inv_J, dNdS);
}
}
else {
for (UInt p = 0; p < nb_points; ++p) {
Matrix<Real> shape_deriv_p = shape_deriv(p);
interpolation_element::computeDNDS(natural_coord(p), shape_deriv_p, real_nodal_coord, n);
}
}
}
/// compute jacobian (or integration variable change factor) for a given point
static inline void computeJacobian(const Matrix<Real> & natural_coords,
const Matrix<Real> & nodal_coords,
Vector<Real> & jacobians) {
parent_element::computeJacobian(natural_coords, nodal_coords, jacobians);
}
public:
static AKANTU_GET_MACRO_NOT_CONST(Kind, _ek_structural, ElementKind);
static AKANTU_GET_MACRO_NOT_CONST(P1ElementType, _not_defined, ElementType);
static AKANTU_GET_MACRO_NOT_CONST(FacetType, _not_defined, ElementType);
static const ElementType getFacetType(UInt t = 0) { return _not_defined; }
static AKANTU_GET_MACRO_NOT_CONST(SpatialDimension, ElementClassProperty<element_type>::spatial_dimension, UInt);
static ElementType * getFacetTypeInternal() { return NULL; }
};
#include "element_classes/element_class_bernoulli_beam_inline_impl.cc"
#include "element_classes/element_class_kirchhoff_shell_inline_impl.cc"
__END_AKANTU__
diff --git a/src/fe_engine/element_class_tmpl.hh b/src/fe_engine/element_class_tmpl.hh
index 65cfd8b0e..a30b1d7b2 100644
--- a/src/fe_engine/element_class_tmpl.hh
+++ b/src/fe_engine/element_class_tmpl.hh
@@ -1,582 +1,583 @@
/**
* @file element_class_tmpl.hh
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Thomas Menouillard <tmenouillard@stucky.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Thu Oct 22 2015
*
* @brief Implementation of the inline templated function of the element class
* descriptions
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* GaussIntegrationElement */
/* -------------------------------------------------------------------------- */
template<GaussIntergrationType type, UInt dimension, UInt order>
struct GaussIntergrationTypeDataHelper {
typedef GaussIntegrationTypeData<type, order> git_data;
static UInt getNbQuadraturePoints() {
return git_data::nb_quadrature_points;
}
static const Matrix<Real> getQuadraturePoints() {
return Matrix<Real>(git_data::quad_positions,
dimension,
git_data::nb_quadrature_points);
}
static const Vector<Real> getWeights() {
return Vector<Real>(git_data::quad_weights,
git_data::nb_quadrature_points);
}
};
/* -------------------------------------------------------------------------- */
template<UInt dimension, UInt order>
struct GaussIntergrationTypeDataHelper<_git_segment, dimension, order> {
typedef GaussIntegrationTypeData<_git_segment, order> git_data;
static UInt getNbQuadraturePoints() {
return Math::pow<dimension>(git_data::nb_quadrature_points);
}
static const Matrix<Real> getQuadraturePoints() {
UInt tot_nquad = getNbQuadraturePoints();
UInt nquad = git_data::nb_quadrature_points;
Matrix<Real> quads(dimension,
tot_nquad);
Vector<Real> pos(git_data::quad_positions,
nquad);
UInt offset = 1;
for (UInt d = 0; d < dimension; ++d) {
for (UInt n = 0, q = 0; n < tot_nquad; ++n, q += offset) {
UInt rq = q % tot_nquad + q / tot_nquad;
quads(d, rq) = pos(n % nquad);
}
offset *= nquad;
}
return quads;
}
static const Vector<Real> getWeights() {
UInt tot_nquad = getNbQuadraturePoints();
UInt nquad = git_data::nb_quadrature_points;
Vector<Real> quads_weights(tot_nquad, 1.);
Vector<Real> weights(git_data::quad_weights,
nquad);
UInt offset = 1;
for (UInt d = 0; d < dimension; ++d) {
for (UInt n = 0, q = 0; n < tot_nquad; ++n, q += offset) {
UInt rq = q % tot_nquad + q / tot_nquad;
quads_weights(rq) *= weights(n % nquad);
}
offset *= nquad;
}
return quads_weights;
}
};
template<ElementType element_type, UInt order>
const Matrix<Real> GaussIntegrationElement<element_type, order>::getQuadraturePoints() {
const InterpolationType itp_type = ElementClassProperty<element_type>::interpolation_type;
typedef InterpolationPorperty<itp_type> interpolation_property;
typedef GaussIntergrationTypeDataHelper<ElementClassProperty<element_type>::gauss_integration_type,
interpolation_property::natural_space_dimension,
order> data_helper;
Matrix<Real> tmp(data_helper::getQuadraturePoints());
return tmp;
}
/* -------------------------------------------------------------------------- */
template<ElementType element_type, UInt order>
const Vector<Real> GaussIntegrationElement<element_type, order>::getWeights() {
const InterpolationType itp_type = ElementClassProperty<element_type>::interpolation_type;
typedef InterpolationPorperty<itp_type> interpolation_property;
typedef GaussIntergrationTypeDataHelper<ElementClassProperty<element_type>::gauss_integration_type,
interpolation_property::natural_space_dimension,
order> data_helper;
Vector<Real> tmp(data_helper::getWeights());
return tmp;
}
/* -------------------------------------------------------------------------- */
template<ElementType element_type, UInt order>
UInt GaussIntegrationElement<element_type, order>::getNbQuadraturePoints() {
const InterpolationType itp_type = ElementClassProperty<element_type>::interpolation_type;
typedef InterpolationPorperty<itp_type> interpolation_property;
typedef GaussIntergrationTypeDataHelper<ElementClassProperty<element_type>::gauss_integration_type,
interpolation_property::natural_space_dimension,
order> data_helper;
return data_helper::getNbQuadraturePoints();
}
/* -------------------------------------------------------------------------- */
/* GeometricalElement */
/* -------------------------------------------------------------------------- */
template<GeometricalType geometrical_type, GeometricalShapeType shape>
inline const MatrixProxy<UInt>
GeometricalElement<geometrical_type, shape>::getFacetLocalConnectivityPerElement(UInt t) {
return MatrixProxy<UInt>(facet_connectivity[t], nb_facets[t], nb_nodes_per_facet[t]);
}
/* -------------------------------------------------------------------------- */
template<GeometricalType geometrical_type, GeometricalShapeType shape>
inline UInt
GeometricalElement<geometrical_type, shape>::getNbFacetsPerElement() {
UInt total_nb_facets = 0;
for(UInt n = 0; n < nb_facet_types; ++n) {
total_nb_facets += nb_facets[n];
}
return total_nb_facets;
}
/* -------------------------------------------------------------------------- */
template<GeometricalType geometrical_type, GeometricalShapeType shape>
inline UInt
GeometricalElement<geometrical_type, shape>::getNbFacetsPerElement(UInt t) {
return nb_facets[t];
}
/* -------------------------------------------------------------------------- */
template<GeometricalType geometrical_type, GeometricalShapeType shape>
template <class vector_type>
inline bool
GeometricalElement<geometrical_type, shape>::contains(const vector_type & coords) {
return GeometricalShapeContains<shape>::contains(coords);
}
/* -------------------------------------------------------------------------- */
template<>
template <class vector_type>
inline bool
GeometricalShapeContains<_gst_point>::contains(const vector_type & coords) {
return (coords(0) < std::numeric_limits<Real>::epsilon());
}
/* -------------------------------------------------------------------------- */
template<>
template <class vector_type>
inline bool
GeometricalShapeContains<_gst_square>::contains(const vector_type & coords) {
bool in = true;
for (UInt i = 0; i < coords.size() && in; ++i)
in &= ((coords(i) >= -(1. + std::numeric_limits<Real>::epsilon() )) && (coords(i) <= (1. + std::numeric_limits<Real>::epsilon())));
return in;
}
/* -------------------------------------------------------------------------- */
template<>
template <class vector_type>
inline bool
GeometricalShapeContains<_gst_triangle>::contains(const vector_type & coords) {
bool in = true;
Real sum = 0;
for (UInt i = 0; (i < coords.size()) && in; ++i) {
in &= ((coords(i) >= - (Math::getTolerance())) && (coords(i) <= (1. + Math::getTolerance())));
sum += coords(i);
}
if(in) return (in && (sum <= (1. + Math::getTolerance())));
return in;
}
/* -------------------------------------------------------------------------- */
template<>
template <class vector_type>
inline bool
GeometricalShapeContains<_gst_prism>::contains(const vector_type & coords) {
bool in = ((coords(0) >= -1.) && (coords(0) <= 1.)); // x in segment [-1, 1]
// y and z in triangle
in &= ((coords(1) >= 0) && (coords(1) <= 1.));
in &= ((coords(2) >= 0) && (coords(2) <= 1.));
Real sum = coords(1) + coords(2);
return (in && (sum <= 1));
}
/* -------------------------------------------------------------------------- */
/* InterpolationElement */
/* -------------------------------------------------------------------------- */
template<InterpolationType interpolation_type, InterpolationKind kind>
inline void
InterpolationElement<interpolation_type, kind>::computeShapes(const Matrix<Real> & natural_coord,
Matrix<Real> & N) {
UInt nb_points = natural_coord.cols();
for (UInt p = 0; p < nb_points; ++p) {
Vector<Real> Np(N(p));
Vector<Real> ncoord_p(natural_coord(p));
computeShapes(ncoord_p, Np);
}
}
/* -------------------------------------------------------------------------- */
template<InterpolationType interpolation_type, InterpolationKind kind>
inline void
InterpolationElement<interpolation_type, kind>::computeDNDS(const Matrix<Real> & natural_coord,
Tensor3<Real> & dnds) {
UInt nb_points = natural_coord.cols();
for (UInt p = 0; p < nb_points; ++p) {
Matrix<Real> dnds_p(dnds(p));
Vector<Real> ncoord_p(natural_coord(p));
computeDNDS(ncoord_p, dnds_p);
}
}
/* -------------------------------------------------------------------------- */
/**
* interpolate on a point a field for which values are given on the
* node of the element using the shape functions at this interpolation point
*
* @param nodal_values values of the function per node @f$ f_{ij} = f_{n_i j} @f$ so it should be a matrix of size nb_nodes_per_element @f$\times@f$ nb_degree_of_freedom
* @param shapes value of shape functions at the interpolation point
* @param interpolated interpolated value of f @f$ f_j(\xi) = \sum_i f_{n_i j} N_i @f$
*/
template<InterpolationType interpolation_type, InterpolationKind kind>
inline void
InterpolationElement<interpolation_type, kind>::interpolate(const Matrix<Real> & nodal_values,
const Vector<Real> & shapes,
Vector<Real> & interpolated) {
Matrix<Real> interpm(interpolated.storage(), nodal_values.rows(), 1);
Matrix<Real> shapesm(shapes.storage(), InterpolationPorperty<interpolation_type>::nb_nodes_per_element, 1);
interpm.mul<false, false>(nodal_values, shapesm);
}
/* -------------------------------------------------------------------------- */
/**
* interpolate on several points a field for which values are given on the
* node of the element using the shape functions at the interpolation point
*
* @param nodal_values values of the function per node @f$ f_{ij} = f_{n_i j} @f$ so it should be a matrix of size nb_nodes_per_element @f$\times@f$ nb_degree_of_freedom
* @param shapes value of shape functions at the interpolation point
* @param interpolated interpolated values of f @f$ f_j(\xi) = \sum_i f_{n_i j} N_i @f$
*/
template<InterpolationType interpolation_type, InterpolationKind kind>
inline void
InterpolationElement<interpolation_type, kind>::interpolate(const Matrix<Real> & nodal_values,
const Matrix<Real> & shapes,
Matrix<Real> & interpolated) {
UInt nb_points = shapes.cols();
for (UInt p = 0; p < nb_points; ++p) {
Vector<Real> Np(shapes(p));
Vector<Real> interpolated_p(interpolated(p));
interpolate(nodal_values, Np, interpolated_p);
}
}
/* -------------------------------------------------------------------------- */
/**
* interpolate the field on a point given in natural coordinates the field which
* values are given on the node of the element
*
* @param natural_coords natural coordinates of point where to interpolate \xi
* @param nodal_values values of the function per node @f$ f_{ij} = f_{n_i j} @f$ so it should be a matrix of size nb_nodes_per_element @f$\times@f$ nb_degree_of_freedom
* @param interpolated interpolated value of f @f$ f_j(\xi) = \sum_i f_{n_i j} N_i @f$
*/
template<InterpolationType interpolation_type, InterpolationKind kind>
inline void
InterpolationElement<interpolation_type, kind>::interpolateOnNaturalCoordinates(const Vector<Real> & natural_coords,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated) {
Vector<Real> shapes(InterpolationPorperty<interpolation_type>::nb_nodes_per_element);
computeShapes(natural_coords, shapes);
interpolate(nodal_values, shapes, interpolated);
}
/* -------------------------------------------------------------------------- */
/// @f$ gradient_{ij} = \frac{\partial f_j}{\partial s_i} = \sum_k \frac{\partial N_k}{\partial s_i}f_{j n_k} @f$
template<InterpolationType interpolation_type, InterpolationKind kind>
inline void
InterpolationElement<interpolation_type, kind>::gradientOnNaturalCoordinates(const Vector<Real> & natural_coords,
const Matrix<Real> & f,
Matrix<Real> & gradient) {
Matrix<Real> dnds(InterpolationPorperty<interpolation_type>::natural_space_dimension,
InterpolationPorperty<interpolation_type>::nb_nodes_per_element);
computeDNDS(natural_coords, dnds);
gradient.mul<false, true>(f, dnds);
}
/* -------------------------------------------------------------------------- */
/* ElementClass */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template <ElementType type, ElementKind kind>
inline void ElementClass<type, kind>::computeJMat(const Tensor3<Real> & dnds,
const Matrix<Real> & node_coords,
Tensor3<Real> & J) {
UInt nb_points = dnds.size(2);
for (UInt p = 0; p < nb_points; ++p) {
Matrix<Real> J_p(J(p));
Matrix<Real> dnds_p(dnds(p));
computeJMat(dnds_p, node_coords, J_p);
}
}
/* -------------------------------------------------------------------------- */
template <ElementType type, ElementKind kind>
inline void ElementClass<type, kind>::computeJMat(const Matrix<Real> & dnds,
const Matrix<Real> & node_coords,
Matrix<Real> & J) {
/// @f$ J = dxds = dnds * x @f$
J.mul<false, true>(dnds, node_coords);
}
/* -------------------------------------------------------------------------- */
template <ElementType type, ElementKind kind>
inline void ElementClass<type, kind>::computeJacobian(const Matrix<Real> & natural_coords,
const Matrix<Real> & node_coords,
Vector<Real> & jacobians) {
UInt nb_points = natural_coords.cols();
Matrix<Real> dnds(interpolation_property::natural_space_dimension,
interpolation_property::nb_nodes_per_element);
Matrix<Real> J(natural_coords.rows(),
node_coords.rows());
for (UInt p = 0; p < nb_points; ++p) {
Vector<Real> ncoord_p(natural_coords(p));
interpolation_element::computeDNDS(ncoord_p, dnds);
computeJMat(dnds, node_coords, J);
computeJacobian(J, jacobians(p));
}
}
/* -------------------------------------------------------------------------- */
template <ElementType type, ElementKind kind>
inline void ElementClass<type, kind>::computeJacobian(const Tensor3<Real> & J,
Vector<Real> & jacobians) {
UInt nb_points = J.size(2);
for (UInt p = 0; p < nb_points; ++p) {
computeJacobian(J(p), jacobians(p));
}
}
/* -------------------------------------------------------------------------- */
template <ElementType type, ElementKind kind>
inline void ElementClass<type, kind>::computeJacobian(const Matrix<Real> & J,
Real & jacobians) {
if(J.rows() == J.cols()) {
jacobians = Math::det<element_property::spatial_dimension>(J.storage());
} else {
interpolation_element::computeSpecialJacobian(J, jacobians);
}
}
/* -------------------------------------------------------------------------- */
template <ElementType type, ElementKind kind>
inline void
ElementClass<type, kind>::computeShapeDerivatives(const Tensor3<Real> & J,
const Tensor3<Real> & dnds,
Tensor3<Real> & shape_deriv) {
UInt nb_points = J.size(2);
for (UInt p = 0; p < nb_points; ++p) {
Matrix<Real> shape_deriv_p(shape_deriv(p));
computeShapeDerivatives(J(p), dnds(p), shape_deriv_p);
}
}
/* -------------------------------------------------------------------------- */
template <ElementType type, ElementKind kind>
inline void
ElementClass<type, kind>::computeShapeDerivatives(const Matrix<Real> & J,
const Matrix<Real> & dnds,
Matrix<Real> & shape_deriv) {
Matrix<Real> inv_J(J.rows(), J.cols());
Math::inv<element_property::spatial_dimension>(J.storage(), inv_J.storage());
shape_deriv.mul<false, false>(inv_J, dnds);
}
/* -------------------------------------------------------------------------- */
template<ElementType type, ElementKind kind>
inline void
ElementClass<type, kind>::computeNormalsOnNaturalCoordinates(const Matrix<Real> & coord,
Matrix<Real> & f,
Matrix<Real> & normals) {
UInt dimension = normals.rows();
UInt nb_points = coord.cols();
AKANTU_DEBUG_ASSERT((dimension - 1) == interpolation_property::natural_space_dimension,
"cannot extract a normal because of dimension mismatch "
<< dimension - 1 << " " << interpolation_property::natural_space_dimension);
Matrix<Real> J(dimension, interpolation_property::natural_space_dimension);
for (UInt p = 0; p < nb_points; ++p) {
interpolation_element::gradientOnNaturalCoordinates(coord(p), f, J);
if (dimension == 2) {
Math::normal2(J.storage(), normals(p).storage());
}
if (dimension == 3){
Math::normal3(J(0).storage(), J(1).storage(), normals(p).storage());
}
}
}
/* ------------------------------------------------------------------------- */
/**
* In the non linear cases we need to iterate to find the natural coordinates @f$\xi@f$
* provided real coordinates @f$x@f$.
*
* We want to solve: @f$ x- \phi(\xi) = 0@f$ with @f$\phi(\xi) = \sum_I N_I(\xi) x_I@f$
* the mapping function which uses the nodal coordinates @f$x_I@f$.
*
* To that end we use the Newton method and the following series:
*
* @f$ \frac{\partial \phi(x_k)}{\partial \xi} \left( \xi_{k+1} - \xi_k \right) = x - \phi(x_k)@f$
*
* When we consider elements embedded in a dimension higher than them (2D triangle in a 3D space for example)
* @f$ J = \frac{\partial \phi(\xi_k)}{\partial \xi}@f$ is of dimension @f$dim_{space} \times dim_{elem}@f$ which
* is not invertible in most cases. Rather we can solve the problem:
*
* @f$ J^T J \left( \xi_{k+1} - \xi_k \right) = J^T \left( x - \phi(\xi_k) \right) @f$
*
* So that
*
* @f$ d\xi = \xi_{k+1} - \xi_k = (J^T J)^{-1} J^T \left( x - \phi(\xi_k) \right) @f$
*
* So that if the series converges we have:
*
* @f$ 0 = J^T \left( \phi(\xi_\infty) - x \right) @f$
*
* And we see that this is ill-posed only if @f$ J^T x = 0@f$ which means that the vector provided
* is normal to any tangent which means it is outside of the element itself.
*
* @param real_coords: the real coordinates the natural coordinates are sought for
* @param node_coords: the coordinates of the nodes forming the element
* @param natural_coords: output->the sought natural coordinates
* @param spatial_dimension: spatial dimension of the problem
*
**/
template <ElementType type, ElementKind kind>
inline void ElementClass<type, kind>::inverseMap(const Vector<Real> & real_coords,
const Matrix<Real> & node_coords,
Vector<Real> & natural_coords,
Real tolerance) {
UInt spatial_dimension = real_coords.size();
UInt dimension = natural_coords.size();
//matrix copy of the real_coords
Matrix<Real> mreal_coords(real_coords.storage(), spatial_dimension, 1);
//initial guess
// Matrix<Real> natural_guess(natural_coords.storage(), dimension, 1);
natural_coords.clear();
// real space coordinates provided by initial guess
Matrix<Real> physical_guess(dimension, 1);
// objective function f = real_coords - physical_guess
Matrix<Real> f(dimension, 1);
// dnds computed on the natural_guess
// Matrix<Real> dnds(interpolation_element::nb_nodes_per_element, spatial_dimension);
// J Jacobian matrix computed on the natural_guess
Matrix<Real> J(spatial_dimension, dimension);
// G = J^t * J
Matrix<Real> G(spatial_dimension, spatial_dimension);
// Ginv = G^{-1}
Matrix<Real> Ginv(spatial_dimension, spatial_dimension);
// J = Ginv * J^t
Matrix<Real> F(spatial_dimension, dimension);
// dxi = \xi_{k+1} - \xi in the iterative process
Matrix<Real> dxi(spatial_dimension, 1);
/* --------------------------- */
/* init before iteration loop */
/* --------------------------- */
// do interpolation
Vector<Real> physical_guess_v(physical_guess.storage(), dimension);
interpolation_element::interpolateOnNaturalCoordinates(natural_coords,
node_coords,
physical_guess_v);
// compute initial objective function value f = real_coords - physical_guess
f = mreal_coords;
f -= physical_guess;
// compute initial error
Real inverse_map_error = f.norm<L_2>();
/* --------------------------- */
/* iteration loop */
/* --------------------------- */
while(tolerance < inverse_map_error) {
//compute J^t
interpolation_element::gradientOnNaturalCoordinates(natural_coords, node_coords, J);
//compute G
G.mul<true, false>(J, J);
// inverse G
Ginv.inverse(G);
//compute F
F.mul<false, true>(Ginv, J);
//compute increment
dxi.mul<false,false>(F, f);
//update our guess
natural_coords += Vector<Real>(dxi(0));
//interpolate
interpolation_element::interpolateOnNaturalCoordinates(natural_coords,
node_coords,
physical_guess_v);
// compute error
f = mreal_coords;
f -= physical_guess;
inverse_map_error = f.norm<L_2>();
}
// memcpy(natural_coords.storage(), natural_guess.storage(), sizeof(Real) * natural_coords.size());
}
/* -------------------------------------------------------------------------- */
template <ElementType type, ElementKind kind>
inline void ElementClass<type, kind>::inverseMap(const Matrix<Real> & real_coords,
const Matrix<Real> & node_coords,
Matrix<Real> & natural_coords,
Real tolerance) {
UInt nb_points = real_coords.cols();
for (UInt p = 0; p < nb_points; ++p) {
Vector<Real> X(real_coords(p));
Vector<Real> ncoord_p(natural_coords(p));
inverseMap(X, node_coords, ncoord_p, tolerance);
}
}
diff --git a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc
index a463db107..1b38affd4 100644
--- a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc
@@ -1,194 +1,195 @@
/**
* @file element_class_bernoulli_beam_inline_impl.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Mon Jul 07 2014
+ * @date creation: Fri Jul 15 2011
+ * @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _bernoulli_beam_2
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
--x-----q1----|----q2-----x---> x
-a 0 a
@endverbatim
*
* @subsection coords Nodes coordinates
*
* @f[
* \begin{array}{ll}
* x_{1} = -a & x_{2} = a
* \end{array}
* @f]
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{ll}
* N_1(x) &= \frac{1-x}{2a}\\
* N_2(x) &= \frac{1+x}{2a}
* \end{array}
*
* \begin{array}{ll}
* M_1(x) &= 1/4(x^{3}/a^{3}-3x/a+2)\\
* M_2(x) &= -1/4(x^{3}/a^{3}-3x/a-2)
* \end{array}
*
* \begin{array}{ll}
* L_1(x) &= a/4(x^{3}/a^{3}-x^{2}/a^{2}-x/a+1)\\
* L_2(x) &= a/4(x^{3}/a^{3}+x^{2}/a^{2}-x/a-1)
* \end{array}
*
* \begin{array}{ll}
* M'_1(x) &= 3/4a(x^{2}/a^{2}-1)\\
* M'_2(x) &= -3/4a(x^{2}/a^{2}-1)
* \end{array}
*
* \begin{array}{ll}
* L'_1(x) &= 1/4(3x^{2}/a^{2}-2x/a-1)\\
* L'_2(x) &= 1/4(3x^{2}/a^{2}+2x/a-1)
* \end{array}
*@f]
*
* @subsection dnds Shape derivatives
*
*@f[
* \begin{array}{ll}
* N'_1(x) &= -1/2a\\
* N'_2(x) &= 1/2a
* \end{array}]
*
* \begin{array}{ll}
* -M''_1(x) &= -3x/(2a^{3})\\
* -M''_2(x) &= 3x/(2a^{3})\\
* \end{array}
*
* \begin{array}{ll}
* -L''_1(x) &= -1/2a(3x/a-1)\\
* -L''_2(x) &= -1/2a(3x/a+1)
* \end{array}
*@f]
*
* @subsection quad_points Position of quadrature points
*
* @f[
* \begin{array}{ll}
* x_{q1} = -a/\sqrt{3} & x_{q2} = a/\sqrt{3}
* \end{array}
* @f]
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_2,
_gt_segment_2,
_itp_bernoulli_beam,
_segment_2,
_ek_structural,
2,
_git_segment, 4);
AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_3,
_gt_segment_2,
_itp_bernoulli_beam,
_segment_2,
_ek_structural,
3,
_git_segment, 4);
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_bernoulli_beam>::computeShapes(const Vector<Real> & natural_coords,
Vector<Real> & N,
const Matrix<Real> & real_coord,
UInt id) {
/// Compute the dimension of the beam
Vector<Real> x1 = real_coord(0);
Vector<Real> x2 = real_coord(1);
Real a = .5 * x1.distance(x2);
/// natural coordinate
Real c = natural_coords(0);
switch (id) {
case 0: { // N
N(0) = 0.5*(1 - c);
N(1) = 0.5*(1 + c);
break;
}
case 1: { // M
N(0) = 0.25 * (c*c*c - 3*c + 2);
N(1) = -0.25 * (c*c*c - 3*c - 2);
break;
}
case 2: { // L
N(0) = 0.25*a * (c*c*c - c*c - c + 1);
N(1) = 0.25*a * (c*c*c + c*c - c - 1);
break;
}
case 3: { // M'
N(0) = 0.75/a * (c*c - 1);
N(1) = -0.75/a * (c*c - 1);
break;
}
case 4: { // L'
N(0) = 0.25 * (3*c*c - 2*c - 1);
N(1) = 0.25 * (3*c*c + 2*c - 1);
break;
}
}
}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_bernoulli_beam>::computeDNDS(const Vector<Real> & natural_coords,
Matrix<Real> & dnds,
const Matrix<Real> & real_nodes_coord,
UInt id) {
/// Compute the dimension of the beam
Vector<Real> x1 = real_nodes_coord(0);
Vector<Real> x2 = real_nodes_coord(1);
Real a = .5 * x1.distance(x2);
/// natural coordinate
Real c = natural_coords(0)*a;
switch (id) {
case 0: { // N'
dnds(0, 0) = -0.5/a;
dnds(0, 1) = 0.5/a;
break;
}
case 1: { // M''
dnds(0, 0) = -3.*c/(2.*pow(a,3));
dnds(0, 1) = 3.*c/(2.*pow(a,3));
break;
}
case 2: { // L''
dnds(0, 0) = -0.5/a * (3*c/a - 1);
dnds(0, 1) =- 0.5/a * (3*c/a + 1);
break;
}
}
}
diff --git a/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc b/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
index 715fe3387..971f815fd 100644
--- a/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
@@ -1,239 +1,236 @@
-/**
- * @file element_class_hexahedron_20_inline_impl.cc
- *
- * @author Sacha Laffely <sacha.laffely@epfl.ch>
- * @author Damien Scantamburlo <damien.scantamburlo@epfl.ch>
- *
- * @date creation: Wed Mar 19 2015
- *
- * @brief Specialization of the element_class class for the type _hexahedron_20
- *
- * @section LICENSE
- *
- * Copyright (©) 2010-2012, 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
- *
- * @verbatim
-
- \y
- \z /
- | /
- 7-----|18--------6
- /| | / /|
- / | | / / |
- 19 | | / 17 |
- / 15 | / / 14
- / | | / / |
- 4-------16---/---5 |
- | | +----|------------\x
- | 3-------10-|-----2
- | / | /
- 12 / 13 /
- | 11 | 9
- | / | /
- |/ |/
- 0--------8-------1
-
-
- x y z
-* N0 -1 -1 -1
-* N1 1 -1 -1
-* N2 1 1 -1
-* N3 -1 1 -1
-* N4 -1 -1 1
-* N5 1 -1 1
-* N6 1 1 1
-* N7 -1 1 1
-* N8 0 -1 -1
-* N9 1 0 -1
-* N10 0 1 -1
-* N11 -1 0 -1
-* N12 -1 -1 0
-* N13 1 -1 0
-* N14 1 1 0
-* N15 -1 1 0
-* N16 0 -1 1
-* N17 1 0 1
-* N18 0 1 1
-* N19 -1 0 1
-
-*/
-
-
-/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_hexahedron_20,
- _gt_hexahedron_20,
- _itp_serendip_hexahedron_20,
- _ek_regular,
- 3,
- _git_segment,
- 3);
-
-AKANTU_DEFINE_SHAPE(_gt_hexahedron_20, _gst_square);
-
-/* -------------------------------------------------------------------------- */
-template <>
-template <class vector_type>
-inline void
-InterpolationElement<_itp_serendip_hexahedron_20>::computeShapes(const vector_type & c,
- vector_type & N) {
-
- // Shape function , Natural coordinates
- N( 0) = 0.125 * (1 - c(0)) * (1 - c(1)) * (1 - c(2)) * (-2 - c(0) - c(1) - c(2));
- N( 1) = 0.125 * (1 + c(0)) * (1 - c(1)) * (1 - c(2)) * (-2 + c(0) - c(1) - c(2));
- N( 2) = 0.125 * (1 + c(0)) * (1 + c(1)) * (1 - c(2)) * (-2 + c(0) + c(1) - c(2));
- N( 3) = 0.125 * (1 - c(0)) * (1 + c(1)) * (1 - c(2)) * (-2 - c(0) + c(1) - c(2));
- N( 4) = 0.125 * (1 - c(0)) * (1 - c(1)) * (1 + c(2)) * (-2 - c(0) - c(1) + c(2));
- N( 5) = 0.125 * (1 + c(0)) * (1 - c(1)) * (1 + c(2)) * (-2 + c(0) - c(1) + c(2));
- N( 6) = 0.125 * (1 + c(0)) * (1 + c(1)) * (1 + c(2)) * (-2 + c(0) + c(1) + c(2));
- N( 7) = 0.125 * (1 - c(0)) * (1 + c(1)) * (1 + c(2)) * (-2 - c(0) + c(1) + c(2));
- N( 8) = 0.25 * (1 - c(0)*c(0)) * (1 - c(1)) * (1 - c(2));
- N( 9) = 0.25 * (1 - c(1)*c(1)) * (1 + c(0)) * (1 - c(2));
- N(10) = 0.25 * (1 - c(0)*c(0)) * (1 + c(1)) * (1 - c(2));
- N(11) = 0.25 * (1 - c(1)*c(1)) * (1 - c(0)) * (1 - c(2));
- N(12) = 0.25 * (1 - c(2)*c(2)) * (1 - c(0)) * (1 - c(1));
- N(13) = 0.25 * (1 - c(2)*c(2)) * (1 + c(0)) * (1 - c(1));
- N(14) = 0.25 * (1 - c(2)*c(2)) * (1 + c(0)) * (1 + c(1));
- N(15) = 0.25 * (1 - c(2)*c(2)) * (1 - c(0)) * (1 + c(1));
- N(16) = 0.25 * (1 - c(0)*c(0)) * (1 - c(1)) * (1 + c(2));
- N(17) = 0.25 * (1 - c(1)*c(1)) * (1 + c(0)) * (1 + c(2));
- N(18) = 0.25 * (1 - c(0)*c(0)) * (1 + c(1)) * (1 + c(2));
- N(19) = 0.25 * (1 - c(1)*c(1)) * (1 - c(0)) * (1 + c(2));
-}
-/* -------------------------------------------------------------------------- */
-
-template <>
-template <class vector_type, class matrix_type>
-inline void
-InterpolationElement<_itp_serendip_hexahedron_20>::computeDNDS(const vector_type & c,
- matrix_type & dnds) {
- //derivatives
- //ddx
- dnds(0, 0) = 0.25 * (c(0) + 0.5 * (c(1) + c(2) + 1)) * (c(1) - 1) * (c(2) - 1);
- dnds(0, 1) = 0.25 * (c(0) - 0.5 * (c(1) + c(2) + 1)) * (c(1) - 1) * (c(2) - 1);
- dnds(0, 2) = -0.25 * (c(0) + 0.5 * (c(1) - c(2) - 1)) * (c(1) + 1) * (c(2) - 1);
- dnds(0, 3) = -0.25 * (c(0) - 0.5 * (c(1) - c(2) - 1)) * (c(1) + 1) * (c(2) - 1);
- dnds(0, 4) = -0.25 * (c(0) + 0.5 * (c(1) - c(2) + 1)) * (c(1) - 1) * (c(2) + 1);
- dnds(0, 5) = -0.25 * (c(0) - 0.5 * (c(1) - c(2) + 1)) * (c(1) - 1) * (c(2) + 1);
- dnds(0, 6) = 0.25 * (c(0) + 0.5 * (c(1) + c(2) - 1)) * (c(1) + 1) * (c(2) + 1);
- dnds(0, 7) = 0.25 * (c(0) - 0.5 * (c(1) + c(2) - 1)) * (c(1) + 1) * (c(2) + 1);
- dnds(0, 8) = -0.5 * c(0) * (c(1) - 1) * (c(2) - 1);
- dnds(0, 9) = 0.25 * (c(1)*c(1) - 1) * (c(2) - 1);
- dnds(0, 10) = 0.5 * c(0) * (c(1) + 1) * (c(2) - 1);
- dnds(0, 11) = -0.25 * (c(1)*c(1) - 1) * (c(2) - 1);
- dnds(0, 12) = -0.25 * (c(2)*c(2) - 1) * (c(1) - 1);
- dnds(0, 13) = 0.25 * (c(1) - 1) * (c(2)*c(2) - 1);
- dnds(0, 14) = -0.25 * (c(1) + 1) * (c(2)*c(2) - 1);
- dnds(0, 15) = 0.25 * (c(1) + 1) * (c(2)*c(2) - 1);
- dnds(0, 16) = 0.5 * c(0) * (c(1) - 1) * (c(2) + 1);
- dnds(0, 17) = -0.25 * (c(2) + 1) * (c(1)*c(1) - 1);
- dnds(0, 18) = -0.5 * c(0) * (c(1) + 1) * (c(2) + 1);
- dnds(0, 19) = 0.25 * (c(2) + 1) * (c(1)*c(1) - 1);
-
-
- //ddy
- dnds(1, 0) = 0.25 * (c(1) + 0.5 * (c(0) + c(2) + 1)) * (c(0) - 1) * (c(2) - 1);
- dnds(1, 1) = -0.25 * (c(1) - 0.5 * (c(0) - c(2) - 1)) * (c(0) + 1) * (c(2) - 1);
- dnds(1, 2) = -0.25 * (c(1) + 0.5 * (c(0) - c(2) - 1)) * (c(0) + 1) * (c(2) - 1);
- dnds(1, 3) = 0.25 * (c(1) - 0.5 * (c(0) + c(2) + 1)) * (c(0) - 1) * (c(2) - 1);
- dnds(1, 4) = -0.25 * (c(1) + 0.5 * (c(0) - c(2) + 1)) * (c(0) - 1) * (c(2) + 1);
- dnds(1, 5) = 0.25 * (c(1) - 0.5 * (c(0) + c(2) - 1)) * (c(0) + 1) * (c(2) + 1);
- dnds(1, 6) = 0.25 * (c(1) + 0.5 * (c(0) + c(2) - 1)) * (c(0) + 1) * (c(2) + 1);
- dnds(1, 7) = -0.25 * (c(1) - 0.5 * (c(0) - c(2) + 1)) * (c(0) - 1) * (c(2) + 1);
- dnds(1, 8) = -0.25 * (c(0)*c(0) - 1) * (c(2) - 1);
- dnds(1, 9) = 0.5 * c(1) * (c(0) + 1) * (c(2) - 1);
- dnds(1, 10) = 0.25 * (c(0)*c(0) - 1) * (c(2) - 1);
- dnds(1, 11) = -0.5 * c(1) * (c(0) - 1) * (c(2) - 1);
- dnds(1, 12) = -0.25 * (c(2)*c(2) - 1) * (c(0) - 1);
- dnds(1, 13) = 0.25 * (c(0) + 1) * (c(2)*c(2) - 1);
- dnds(1, 14) = -0.25 * (c(0) + 1) * (c(2)*c(2) - 1);
- dnds(1, 15) = 0.25 * (c(0) - 1) * (c(2)*c(2) - 1);
- dnds(1, 16) = 0.25 * (c(2) + 1) * (c(0)*c(0) - 1);
- dnds(1, 17) = -0.5 * c(1) * (c(0) + 1) * (c(2) + 1);
- dnds(1, 18) = -0.25 * (c(2) + 1) * (c(0)*c(0) - 1);
- dnds(1, 19) = 0.5 * c(1) * (c(0) - 1) * (c(2) + 1);
-
- //ddz
- dnds(2, 0) = 0.25 * (c(2) + 0.5 * (c(0) + c(1) + 1)) * (c(0) - 1) * (c(1) - 1);
- dnds(2, 1) = -0.25 * (c(2) - 0.5 * (c(0) - c(1) - 1)) * (c(0) + 1) * (c(1) - 1);
- dnds(2, 2) = 0.25 * (c(2) - 0.5 * (c(0) + c(1) - 1)) * (c(0) + 1) * (c(1) + 1);
- dnds(2, 3) = -0.25 * (c(2) + 0.5 * (c(0) - c(1) + 1)) * (c(0) - 1) * (c(1) + 1);
- dnds(2, 4) = 0.25 * (c(2) - 0.5 * (c(0) + c(1) + 1)) * (c(0) - 1) * (c(1) - 1);
- dnds(2, 5) = -0.25 * (c(2) + 0.5 * (c(0) - c(1) - 1)) * (c(0) + 1) * (c(1) - 1);
- dnds(2, 6) = 0.25 * (c(2) + 0.5 * (c(0) + c(1) - 1)) * (c(0) + 1) * (c(1) + 1);
- dnds(2, 7) = -0.25 * (c(2) - 0.5 * (c(0) - c(1) + 1)) * (c(0) - 1) * (c(1) + 1);
- dnds(2, 8) = -0.25 * (c(0)*c(0) - 1) * (c(1) - 1);
- dnds(2, 9) = 0.25 * (c(1)*c(1) - 1) * (c(0) + 1);
- dnds(2, 10) = 0.25 * (c(0)*c(0) - 1) * (c(1) + 1);
- dnds(2, 11) = -0.25 * (c(1)*c(1) - 1) * (c(0) - 1);
- dnds(2, 12) = -0.5 * c(2) * (c(1) - 1) * (c(0) - 1);
- dnds(2, 13) = 0.5 * c(2) * (c(0) + 1) * (c(1) - 1);
- dnds(2, 14) = -0.5 * c(2) * (c(0) + 1) * (c(1) + 1);
- dnds(2, 15) = 0.5 * c(2) * (c(0) - 1) * (c(1) + 1);
- dnds(2, 16) = 0.25 * (c(1) - 1) * (c(0)*c(0) - 1);
- dnds(2, 17) = -0.25 * (c(0) + 1) * (c(1)*c(1) - 1);
- dnds(2, 18) = -0.25 * (c(1) + 1) * (c(0)*c(0) - 1);
- dnds(2, 19) = 0.25 * (c(0) - 1) * (c(1)*c(1) - 1);
-}
-
-/* -------------------------------------------------------------------------- */
-
-template<>
-inline Real
-GeometricalElement<_gt_hexahedron_20>::getInradius(const Matrix<Real> & coord) {
- Vector<Real> u0 = coord(0);
- Vector<Real> u1 = coord(1);
- Vector<Real> u2 = coord(2);
- Vector<Real> u3 = coord(3);
- Vector<Real> u4 = coord(4);
- Vector<Real> u5 = coord(5);
- Vector<Real> u6 = coord(6);
- Vector<Real> u7 = coord(7);
- Vector<Real> u8 = coord(8);
- Vector<Real> u9 = coord(9);
- Vector<Real> u10 = coord(10);
- Vector<Real> u11= coord(11);
- Vector<Real> u12 = coord(12);
- Vector<Real> u13 = coord(13);
- Vector<Real> u14 = coord(14);
- Vector<Real> u15 = coord(15);
- Vector<Real> u16 = coord(16);
- Vector<Real> u17 = coord(17);
- Vector<Real> u18 = coord(18);
- Vector<Real> u19 = coord(19);
-
- Real a = u0.distance(u1);
- Real b = u1.distance(u2);
- Real c = u2.distance(u3);
- Real d = u3.distance(u0);
- Real e = u0.distance(u4);
- Real f = u1.distance(u5);
- Real g = u2.distance(u6);
- Real h = u3.distance(u7);
- Real i = u4.distance(u5);
- Real j = u5.distance(u6);
- Real k = u6.distance(u7);
- Real l = u7.distance(u4);
-
- Real x = std::min(a, std::min(b, std::min(c, d)));
- Real y = std::min(e, std::min(f, std::min(g, h)));
- Real z = std::min(i, std::min(j, std::min(k, l)));
- Real p = std::min(x, std::min(y, z));
-
- return p;
-}
+/**
+ * @file element_class_hexahedron_20_inline_impl.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Sacha Laffely <sacha.laffely@epfl.ch>
+ * @author Damien Scantamburlo <damien.scantamburlo@epfl.ch>
+ *
+ * @date creation: Tue Mar 31 2015
+ * @date last modification: Thu Jul 16 2015
+ *
+ * @brief Specialization of the element_class class for the type _hexahedron_20
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ * @section DESCRIPTION
+ *
+ * @verbatim
+ \y
+ \z /
+ | /
+ 7-----|18--------6
+ /| | / /|
+ / | | / / |
+ 19 | | / 17 |
+ / 15 | / / 14
+ / | | / / |
+ 4-------16---/---5 |
+ | | +----|------------\x
+ | 3-------10-|-----2
+ | / | /
+ 12 / 13 /
+ | 11 | 9
+ | / | /
+ |/ |/
+ 0--------8-------1
+ x y z
+* N0 -1 -1 -1
+* N1 1 -1 -1
+* N2 1 1 -1
+* N3 -1 1 -1
+* N4 -1 -1 1
+* N5 1 -1 1
+* N6 1 1 1
+* N7 -1 1 1
+* N8 0 -1 -1
+* N9 1 0 -1
+* N10 0 1 -1
+* N11 -1 0 -1
+* N12 -1 -1 0
+* N13 1 -1 0
+* N14 1 1 0
+* N15 -1 1 0
+* N16 0 -1 1
+* N17 1 0 1
+* N18 0 1 1
+* N19 -1 0 1
+ */
+
+/* -------------------------------------------------------------------------- */
+AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_hexahedron_20,
+ _gt_hexahedron_20,
+ _itp_serendip_hexahedron_20,
+ _ek_regular,
+ 3,
+ _git_segment,
+ 3);
+
+AKANTU_DEFINE_SHAPE(_gt_hexahedron_20, _gst_square);
+
+/* -------------------------------------------------------------------------- */
+template <>
+template <class vector_type>
+inline void
+InterpolationElement<_itp_serendip_hexahedron_20>::computeShapes(const vector_type & c,
+ vector_type & N) {
+
+ // Shape function , Natural coordinates
+ N( 0) = 0.125 * (1 - c(0)) * (1 - c(1)) * (1 - c(2)) * (-2 - c(0) - c(1) - c(2));
+ N( 1) = 0.125 * (1 + c(0)) * (1 - c(1)) * (1 - c(2)) * (-2 + c(0) - c(1) - c(2));
+ N( 2) = 0.125 * (1 + c(0)) * (1 + c(1)) * (1 - c(2)) * (-2 + c(0) + c(1) - c(2));
+ N( 3) = 0.125 * (1 - c(0)) * (1 + c(1)) * (1 - c(2)) * (-2 - c(0) + c(1) - c(2));
+ N( 4) = 0.125 * (1 - c(0)) * (1 - c(1)) * (1 + c(2)) * (-2 - c(0) - c(1) + c(2));
+ N( 5) = 0.125 * (1 + c(0)) * (1 - c(1)) * (1 + c(2)) * (-2 + c(0) - c(1) + c(2));
+ N( 6) = 0.125 * (1 + c(0)) * (1 + c(1)) * (1 + c(2)) * (-2 + c(0) + c(1) + c(2));
+ N( 7) = 0.125 * (1 - c(0)) * (1 + c(1)) * (1 + c(2)) * (-2 - c(0) + c(1) + c(2));
+ N( 8) = 0.25 * (1 - c(0)*c(0)) * (1 - c(1)) * (1 - c(2));
+ N( 9) = 0.25 * (1 - c(1)*c(1)) * (1 + c(0)) * (1 - c(2));
+ N(10) = 0.25 * (1 - c(0)*c(0)) * (1 + c(1)) * (1 - c(2));
+ N(11) = 0.25 * (1 - c(1)*c(1)) * (1 - c(0)) * (1 - c(2));
+ N(12) = 0.25 * (1 - c(2)*c(2)) * (1 - c(0)) * (1 - c(1));
+ N(13) = 0.25 * (1 - c(2)*c(2)) * (1 + c(0)) * (1 - c(1));
+ N(14) = 0.25 * (1 - c(2)*c(2)) * (1 + c(0)) * (1 + c(1));
+ N(15) = 0.25 * (1 - c(2)*c(2)) * (1 - c(0)) * (1 + c(1));
+ N(16) = 0.25 * (1 - c(0)*c(0)) * (1 - c(1)) * (1 + c(2));
+ N(17) = 0.25 * (1 - c(1)*c(1)) * (1 + c(0)) * (1 + c(2));
+ N(18) = 0.25 * (1 - c(0)*c(0)) * (1 + c(1)) * (1 + c(2));
+ N(19) = 0.25 * (1 - c(1)*c(1)) * (1 - c(0)) * (1 + c(2));
+}
+/* -------------------------------------------------------------------------- */
+
+template <>
+template <class vector_type, class matrix_type>
+inline void
+InterpolationElement<_itp_serendip_hexahedron_20>::computeDNDS(const vector_type & c,
+ matrix_type & dnds) {
+ //derivatives
+ //ddx
+ dnds(0, 0) = 0.25 * (c(0) + 0.5 * (c(1) + c(2) + 1)) * (c(1) - 1) * (c(2) - 1);
+ dnds(0, 1) = 0.25 * (c(0) - 0.5 * (c(1) + c(2) + 1)) * (c(1) - 1) * (c(2) - 1);
+ dnds(0, 2) = -0.25 * (c(0) + 0.5 * (c(1) - c(2) - 1)) * (c(1) + 1) * (c(2) - 1);
+ dnds(0, 3) = -0.25 * (c(0) - 0.5 * (c(1) - c(2) - 1)) * (c(1) + 1) * (c(2) - 1);
+ dnds(0, 4) = -0.25 * (c(0) + 0.5 * (c(1) - c(2) + 1)) * (c(1) - 1) * (c(2) + 1);
+ dnds(0, 5) = -0.25 * (c(0) - 0.5 * (c(1) - c(2) + 1)) * (c(1) - 1) * (c(2) + 1);
+ dnds(0, 6) = 0.25 * (c(0) + 0.5 * (c(1) + c(2) - 1)) * (c(1) + 1) * (c(2) + 1);
+ dnds(0, 7) = 0.25 * (c(0) - 0.5 * (c(1) + c(2) - 1)) * (c(1) + 1) * (c(2) + 1);
+ dnds(0, 8) = -0.5 * c(0) * (c(1) - 1) * (c(2) - 1);
+ dnds(0, 9) = 0.25 * (c(1)*c(1) - 1) * (c(2) - 1);
+ dnds(0, 10) = 0.5 * c(0) * (c(1) + 1) * (c(2) - 1);
+ dnds(0, 11) = -0.25 * (c(1)*c(1) - 1) * (c(2) - 1);
+ dnds(0, 12) = -0.25 * (c(2)*c(2) - 1) * (c(1) - 1);
+ dnds(0, 13) = 0.25 * (c(1) - 1) * (c(2)*c(2) - 1);
+ dnds(0, 14) = -0.25 * (c(1) + 1) * (c(2)*c(2) - 1);
+ dnds(0, 15) = 0.25 * (c(1) + 1) * (c(2)*c(2) - 1);
+ dnds(0, 16) = 0.5 * c(0) * (c(1) - 1) * (c(2) + 1);
+ dnds(0, 17) = -0.25 * (c(2) + 1) * (c(1)*c(1) - 1);
+ dnds(0, 18) = -0.5 * c(0) * (c(1) + 1) * (c(2) + 1);
+ dnds(0, 19) = 0.25 * (c(2) + 1) * (c(1)*c(1) - 1);
+
+
+ //ddy
+ dnds(1, 0) = 0.25 * (c(1) + 0.5 * (c(0) + c(2) + 1)) * (c(0) - 1) * (c(2) - 1);
+ dnds(1, 1) = -0.25 * (c(1) - 0.5 * (c(0) - c(2) - 1)) * (c(0) + 1) * (c(2) - 1);
+ dnds(1, 2) = -0.25 * (c(1) + 0.5 * (c(0) - c(2) - 1)) * (c(0) + 1) * (c(2) - 1);
+ dnds(1, 3) = 0.25 * (c(1) - 0.5 * (c(0) + c(2) + 1)) * (c(0) - 1) * (c(2) - 1);
+ dnds(1, 4) = -0.25 * (c(1) + 0.5 * (c(0) - c(2) + 1)) * (c(0) - 1) * (c(2) + 1);
+ dnds(1, 5) = 0.25 * (c(1) - 0.5 * (c(0) + c(2) - 1)) * (c(0) + 1) * (c(2) + 1);
+ dnds(1, 6) = 0.25 * (c(1) + 0.5 * (c(0) + c(2) - 1)) * (c(0) + 1) * (c(2) + 1);
+ dnds(1, 7) = -0.25 * (c(1) - 0.5 * (c(0) - c(2) + 1)) * (c(0) - 1) * (c(2) + 1);
+ dnds(1, 8) = -0.25 * (c(0)*c(0) - 1) * (c(2) - 1);
+ dnds(1, 9) = 0.5 * c(1) * (c(0) + 1) * (c(2) - 1);
+ dnds(1, 10) = 0.25 * (c(0)*c(0) - 1) * (c(2) - 1);
+ dnds(1, 11) = -0.5 * c(1) * (c(0) - 1) * (c(2) - 1);
+ dnds(1, 12) = -0.25 * (c(2)*c(2) - 1) * (c(0) - 1);
+ dnds(1, 13) = 0.25 * (c(0) + 1) * (c(2)*c(2) - 1);
+ dnds(1, 14) = -0.25 * (c(0) + 1) * (c(2)*c(2) - 1);
+ dnds(1, 15) = 0.25 * (c(0) - 1) * (c(2)*c(2) - 1);
+ dnds(1, 16) = 0.25 * (c(2) + 1) * (c(0)*c(0) - 1);
+ dnds(1, 17) = -0.5 * c(1) * (c(0) + 1) * (c(2) + 1);
+ dnds(1, 18) = -0.25 * (c(2) + 1) * (c(0)*c(0) - 1);
+ dnds(1, 19) = 0.5 * c(1) * (c(0) - 1) * (c(2) + 1);
+
+ //ddz
+ dnds(2, 0) = 0.25 * (c(2) + 0.5 * (c(0) + c(1) + 1)) * (c(0) - 1) * (c(1) - 1);
+ dnds(2, 1) = -0.25 * (c(2) - 0.5 * (c(0) - c(1) - 1)) * (c(0) + 1) * (c(1) - 1);
+ dnds(2, 2) = 0.25 * (c(2) - 0.5 * (c(0) + c(1) - 1)) * (c(0) + 1) * (c(1) + 1);
+ dnds(2, 3) = -0.25 * (c(2) + 0.5 * (c(0) - c(1) + 1)) * (c(0) - 1) * (c(1) + 1);
+ dnds(2, 4) = 0.25 * (c(2) - 0.5 * (c(0) + c(1) + 1)) * (c(0) - 1) * (c(1) - 1);
+ dnds(2, 5) = -0.25 * (c(2) + 0.5 * (c(0) - c(1) - 1)) * (c(0) + 1) * (c(1) - 1);
+ dnds(2, 6) = 0.25 * (c(2) + 0.5 * (c(0) + c(1) - 1)) * (c(0) + 1) * (c(1) + 1);
+ dnds(2, 7) = -0.25 * (c(2) - 0.5 * (c(0) - c(1) + 1)) * (c(0) - 1) * (c(1) + 1);
+ dnds(2, 8) = -0.25 * (c(0)*c(0) - 1) * (c(1) - 1);
+ dnds(2, 9) = 0.25 * (c(1)*c(1) - 1) * (c(0) + 1);
+ dnds(2, 10) = 0.25 * (c(0)*c(0) - 1) * (c(1) + 1);
+ dnds(2, 11) = -0.25 * (c(1)*c(1) - 1) * (c(0) - 1);
+ dnds(2, 12) = -0.5 * c(2) * (c(1) - 1) * (c(0) - 1);
+ dnds(2, 13) = 0.5 * c(2) * (c(0) + 1) * (c(1) - 1);
+ dnds(2, 14) = -0.5 * c(2) * (c(0) + 1) * (c(1) + 1);
+ dnds(2, 15) = 0.5 * c(2) * (c(0) - 1) * (c(1) + 1);
+ dnds(2, 16) = 0.25 * (c(1) - 1) * (c(0)*c(0) - 1);
+ dnds(2, 17) = -0.25 * (c(0) + 1) * (c(1)*c(1) - 1);
+ dnds(2, 18) = -0.25 * (c(1) + 1) * (c(0)*c(0) - 1);
+ dnds(2, 19) = 0.25 * (c(0) - 1) * (c(1)*c(1) - 1);
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<>
+inline Real
+GeometricalElement<_gt_hexahedron_20>::getInradius(const Matrix<Real> & coord) {
+ Vector<Real> u0 = coord(0);
+ Vector<Real> u1 = coord(1);
+ Vector<Real> u2 = coord(2);
+ Vector<Real> u3 = coord(3);
+ Vector<Real> u4 = coord(4);
+ Vector<Real> u5 = coord(5);
+ Vector<Real> u6 = coord(6);
+ Vector<Real> u7 = coord(7);
+ Vector<Real> u8 = coord(8);
+ Vector<Real> u9 = coord(9);
+ Vector<Real> u10 = coord(10);
+ Vector<Real> u11= coord(11);
+ Vector<Real> u12 = coord(12);
+ Vector<Real> u13 = coord(13);
+ Vector<Real> u14 = coord(14);
+ Vector<Real> u15 = coord(15);
+ Vector<Real> u16 = coord(16);
+ Vector<Real> u17 = coord(17);
+ Vector<Real> u18 = coord(18);
+ Vector<Real> u19 = coord(19);
+
+ Real a = u0.distance(u1);
+ Real b = u1.distance(u2);
+ Real c = u2.distance(u3);
+ Real d = u3.distance(u0);
+ Real e = u0.distance(u4);
+ Real f = u1.distance(u5);
+ Real g = u2.distance(u6);
+ Real h = u3.distance(u7);
+ Real i = u4.distance(u5);
+ Real j = u5.distance(u6);
+ Real k = u6.distance(u7);
+ Real l = u7.distance(u4);
+
+ Real x = std::min(a, std::min(b, std::min(c, d)));
+ Real y = std::min(e, std::min(f, std::min(g, h)));
+ Real z = std::min(i, std::min(j, std::min(k, l)));
+ Real p = std::min(x, std::min(y, z));
+
+ return p;
+}
diff --git a/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc b/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
index d56b54db5..d84a2ad30 100644
--- a/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
@@ -1,214 +1,216 @@
/**
* @file element_class_hexahedron_8_inline_impl.cc
*
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Peter Spijker <peter.spijker@epfl.ch>
*
* @date creation: Mon Mar 14 2011
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sat Sep 12 2015
*
* @brief Specialization of the element_class class for the type _hexahedron_8
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
\zeta
^
(-1,1,1) | (1,1,1)
7---|------6
/| | /|
/ | | / |
(-1,-1,1) 4----------5 | (1,-1,1)
| | | | |
| | | | |
| | +---|-------> \xi
| | / | |
(-1,1,-1) | 3-/-----|--2 (1,1,-1)
| / / | /
|/ / |/
0-/--------1
(-1,-1,-1) / (1,-1,-1)
/
\eta
@endverbatim
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{llll}
* N1 = (1 - \xi) (1 - \eta) (1 - \zeta) / 8
* & \frac{\partial N1}{\partial \xi} = - (1 - \eta) (1 - \zeta) / 8
* & \frac{\partial N1}{\partial \eta} = - (1 - \xi) (1 - \zeta) / 8
* & \frac{\partial N1}{\partial \zeta} = - (1 - \xi) (1 - \eta) / 8 \\
* N2 = (1 + \xi) (1 - \eta) (1 - \zeta) / 8
* & \frac{\partial N2}{\partial \xi} = (1 - \eta) (1 - \zeta) / 8
* & \frac{\partial N2}{\partial \eta} = - (1 + \xi) (1 - \zeta) / 8
* & \frac{\partial N2}{\partial \zeta} = - (1 + \xi) (1 - \eta) / 8 \\
* N3 = (1 + \xi) (1 + \eta) (1 - \zeta) / 8
* & \frac{\partial N3}{\partial \xi} = (1 + \eta) (1 - \zeta) / 8
* & \frac{\partial N3}{\partial \eta} = (1 + \xi) (1 - \zeta) / 8
* & \frac{\partial N3}{\partial \zeta} = - (1 + \xi) (1 + \eta) / 8 \\
* N4 = (1 - \xi) (1 + \eta) (1 - \zeta) / 8
* & \frac{\partial N4}{\partial \xi} = - (1 + \eta) (1 - \zeta) / 8
* & \frac{\partial N4}{\partial \eta} = (1 - \xi) (1 - \zeta) / 8
* & \frac{\partial N4}{\partial \zeta} = - (1 - \xi) (1 + \eta) / 8 \\
* N5 = (1 - \xi) (1 - \eta) (1 + \zeta) / 8
* & \frac{\partial N5}{\partial \xi} = - (1 - \eta) (1 + \zeta) / 8
* & \frac{\partial N5}{\partial \eta} = - (1 - \xi) (1 + \zeta) / 8
* & \frac{\partial N5}{\partial \zeta} = (1 - \xi) (1 - \eta) / 8 \\
* N6 = (1 + \xi) (1 - \eta) (1 + \zeta) / 8
* & \frac{\partial N6}{\partial \xi} = (1 - \eta) (1 + \zeta) / 8
* & \frac{\partial N6}{\partial \eta} = - (1 + \xi) (1 + \zeta) / 8
* & \frac{\partial N6}{\partial \zeta} = (1 + \xi) (1 - \eta) / 8 \\
* N7 = (1 + \xi) (1 + \eta) (1 + \zeta) / 8
* & \frac{\partial N7}{\partial \xi} = (1 + \eta) (1 + \zeta) / 8
* & \frac{\partial N7}{\partial \eta} = (1 + \xi) (1 + \zeta) / 8
* & \frac{\partial N7}{\partial \zeta} = (1 + \xi) (1 + \eta) / 8 \\
* N8 = (1 - \xi) (1 + \eta) (1 + \zeta) / 8
* & \frac{\partial N8}{\partial \xi} = - (1 + \eta) (1 + \zeta) / 8
* & \frac{\partial N8}{\partial \eta} = (1 - \xi) (1 + \zeta) / 8
* & \frac{\partial N8}{\partial \zeta} = (1 - \xi) (1 + \eta) / 8 \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& -1/\sqrt{3} \qquad \eta_{q0} = -1/\sqrt{3} \qquad \zeta_{q0} = -1/\sqrt{3} \\
* \xi_{q1} &=& 1/\sqrt{3} \qquad \eta_{q1} = -1/\sqrt{3} \qquad \zeta_{q1} = -1/\sqrt{3} \\
* \xi_{q2} &=& 1/\sqrt{3} \qquad \eta_{q2} = 1/\sqrt{3} \qquad \zeta_{q2} = -1/\sqrt{3} \\
* \xi_{q3} &=& -1/\sqrt{3} \qquad \eta_{q3} = 1/\sqrt{3} \qquad \zeta_{q3} = -1/\sqrt{3} \\
* \xi_{q4} &=& -1/\sqrt{3} \qquad \eta_{q4} = -1/\sqrt{3} \qquad \zeta_{q4} = 1/\sqrt{3} \\
* \xi_{q5} &=& 1/\sqrt{3} \qquad \eta_{q5} = -1/\sqrt{3} \qquad \zeta_{q5} = 1/\sqrt{3} \\
* \xi_{q6} &=& 1/\sqrt{3} \qquad \eta_{q6} = 1/\sqrt{3} \qquad \zeta_{q6} = 1/\sqrt{3} \\
* \xi_{q7} &=& -1/\sqrt{3} \qquad \eta_{q7} = 1/\sqrt{3} \qquad \zeta_{q7} = 1/\sqrt{3} \\
* @f}
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_hexahedron_8,
_gt_hexahedron_8,
_itp_lagrange_hexahedron_8,
_ek_regular,
3,
_git_segment, 2);
AKANTU_DEFINE_SHAPE(_gt_hexahedron_8, _gst_square);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_hexahedron_8>::computeShapes(const vector_type & c,
vector_type & N) {
/// Natural coordinates
N(0) = .125 * (1 - c(0)) * (1 - c(1)) * (1 - c(2)); /// N1(q_0)
N(1) = .125 * (1 + c(0)) * (1 - c(1)) * (1 - c(2)); /// N2(q_0)
N(2) = .125 * (1 + c(0)) * (1 + c(1)) * (1 - c(2)); /// N3(q_0)
N(3) = .125 * (1 - c(0)) * (1 + c(1)) * (1 - c(2)); /// N4(q_0)
N(4) = .125 * (1 - c(0)) * (1 - c(1)) * (1 + c(2)); /// N5(q_0)
N(5) = .125 * (1 + c(0)) * (1 - c(1)) * (1 + c(2)); /// N6(q_0)
N(6) = .125 * (1 + c(0)) * (1 + c(1)) * (1 + c(2)); /// N7(q_0)
N(7) = .125 * (1 - c(0)) * (1 + c(1)) * (1 + c(2)); /// N8(q_0)
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_hexahedron_8>::computeDNDS(const vector_type & c,
matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccccc}
* \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi}
* & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial \xi}
* & \frac{\partial N5}{\partial \xi} & \frac{\partial N6}{\partial \xi}
* & \frac{\partial N7}{\partial \xi} & \frac{\partial N8}{\partial \xi}\\
* \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta}
* & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial \eta}
* & \frac{\partial N5}{\partial \eta} & \frac{\partial N6}{\partial \eta}
* & \frac{\partial N7}{\partial \eta} & \frac{\partial N8}{\partial \eta}\\
* \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial \zeta}
* & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial \zeta}
* & \frac{\partial N5}{\partial \zeta} & \frac{\partial N6}{\partial \zeta}
* & \frac{\partial N7}{\partial \zeta} & \frac{\partial N8}{\partial \zeta}
* \end{array}
* \right)
* @f]
*/
dnds(0, 0) = - .125 * (1 - c(1)) * (1 - c(2));;
dnds(0, 1) = .125 * (1 - c(1)) * (1 - c(2));;
dnds(0, 2) = .125 * (1 + c(1)) * (1 - c(2));;
dnds(0, 3) = - .125 * (1 + c(1)) * (1 - c(2));;
dnds(0, 4) = - .125 * (1 - c(1)) * (1 + c(2));;
dnds(0, 5) = .125 * (1 - c(1)) * (1 + c(2));;
dnds(0, 6) = .125 * (1 + c(1)) * (1 + c(2));;
dnds(0, 7) = - .125 * (1 + c(1)) * (1 + c(2));;
dnds(1, 0) = - .125 * (1 - c(0)) * (1 - c(2));;
dnds(1, 1) = - .125 * (1 + c(0)) * (1 - c(2));;
dnds(1, 2) = .125 * (1 + c(0)) * (1 - c(2));;
dnds(1, 3) = .125 * (1 - c(0)) * (1 - c(2));;
dnds(1, 4) = - .125 * (1 - c(0)) * (1 + c(2));;
dnds(1, 5) = - .125 * (1 + c(0)) * (1 + c(2));;
dnds(1, 6) = .125 * (1 + c(0)) * (1 + c(2));;
dnds(1, 7) = .125 * (1 - c(0)) * (1 + c(2));;
dnds(2, 0) = - .125 * (1 - c(0)) * (1 - c(1));;
dnds(2, 1) = - .125 * (1 + c(0)) * (1 - c(1));;
dnds(2, 2) = - .125 * (1 + c(0)) * (1 + c(1));;
dnds(2, 3) = - .125 * (1 - c(0)) * (1 + c(1));;
dnds(2, 4) = .125 * (1 - c(0)) * (1 - c(1));;
dnds(2, 5) = .125 * (1 + c(0)) * (1 - c(1));;
dnds(2, 6) = .125 * (1 + c(0)) * (1 + c(1));;
dnds(2, 7) = .125 * (1 - c(0)) * (1 + c(1));;
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_hexahedron_8>::getInradius(const Matrix<Real> & coord) {
Vector<Real> u0 = coord(0);
Vector<Real> u1 = coord(1);
Vector<Real> u2 = coord(2);
Vector<Real> u3 = coord(3);
Vector<Real> u4 = coord(4);
Vector<Real> u5 = coord(5);
Vector<Real> u6 = coord(6);
Vector<Real> u7 = coord(7);
Real a = u0.distance(u1);
Real b = u1.distance(u2);
Real c = u2.distance(u3);
Real d = u3.distance(u0);
Real e = u0.distance(u4);
Real f = u1.distance(u5);
Real g = u2.distance(u6);
Real h = u3.distance(u7);
Real i = u4.distance(u5);
Real j = u5.distance(u6);
Real k = u6.distance(u7);
Real l = u7.distance(u4);
Real x = std::min(a, std::min(b, std::min(c, d)));
Real y = std::min(e, std::min(f, std::min(g, h)));
Real z = std::min(i, std::min(j, std::min(k, l)));
Real p = std::min(x, std::min(y, z));
return p;
}
diff --git a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
index 41365693f..f033f8184 100644
--- a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
@@ -1,287 +1,289 @@
/**
* @file element_class_kirchhoff_shell_inline_impl.cc
*
* @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation: Fri Jul 04 2014
- * @date last modification: Fri Jul 04 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Element class Kirchhoff Shell
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_kirchhoff_shell,
- _gt_triangle_3,
- _itp_kirchhoff_shell,
- _triangle_3,
- _ek_structural,
- 3,
- _git_triangle, 2);
+ _gt_triangle_3,
+ _itp_kirchhoff_shell,
+ _triangle_3, _ek_structural, 3,
+ _git_triangle, 2);
/* -------------------------------------------------------------------------- */
-//cf. element_class_bernoulli...
-//element_class_triangle_3_inline... (pour compute Jacobian)
+// cf. element_class_bernoulli...
+// element_class_triangle_3_inline... (pour compute Jacobian)
template <>
-inline void
-InterpolationElement<_itp_kirchhoff_shell>::computeShapes(const Vector<Real> & natural_coords,
- Vector<Real> & N,
- const Matrix<Real> & projected_coord,
- UInt id) {
+inline void InterpolationElement<_itp_kirchhoff_shell>::computeShapes(
+ const Vector<Real> & natural_coords, Vector<Real> & N,
+ const Matrix<Real> & projected_coord, UInt id) {
// projected_coord (x1 x2 x3) (y1 y2 y3)
-
+
// natural coordinate
Real xi = natural_coords(0);
Real eta = natural_coords(1);
- Real x21=projected_coord(0,0)-projected_coord(0,1); //x1-x2
- Real x32=projected_coord(0,1)-projected_coord(0,2);
- Real x13=projected_coord(0,2)-projected_coord(0,0);
+ Real x21 = projected_coord(0, 0) - projected_coord(0, 1); // x1-x2
+ Real x32 = projected_coord(0, 1) - projected_coord(0, 2);
+ Real x13 = projected_coord(0, 2) - projected_coord(0, 0);
- Real y21=projected_coord(1,0)-projected_coord(1,1); //y1-y2
- Real y32=projected_coord(1,1)-projected_coord(1,2);
- Real y13=projected_coord(1,2)-projected_coord(1,0);
+ Real y21 = projected_coord(1, 0) - projected_coord(1, 1); // y1-y2
+ Real y32 = projected_coord(1, 1) - projected_coord(1, 2);
+ Real y13 = projected_coord(1, 2) - projected_coord(1, 0);
/* Real x21=projected_coord(0,1)-projected_coord(0,0);
Real x32=projected_coord(0,2)-projected_coord(0,1);
Real x13=projected_coord(0,0)-projected_coord(0,2);
Real y21=projected_coord(1,1)-projected_coord(1,0);
Real y32=projected_coord(1,2)-projected_coord(1,1);
Real y13=projected_coord(1,0)-projected_coord(1,2);*/
// natural triangle side length
- Real L4=sqrt(x21*x21+y21*y21);
- Real L5=sqrt(x32*x32+y32*y32);
- Real L6=sqrt(x13*x13+y13*y13);
+ Real L4 = sqrt(x21 * x21 + y21 * y21);
+ Real L5 = sqrt(x32 * x32 + y32 * y32);
+ Real L6 = sqrt(x13 * x13 + y13 * y13);
// sinus and cosinus
- Real C4=x21/L4; //1
- Real C5=x32/L5; //-1/sqrt(2);
- Real C6=x13/L6; //0
- Real S4=y21/L4; //0;
- Real S5=y32/L5; //1/sqrt(2);
- Real S6=y13/L6; //-1;
-
- Real N1 = 1-xi-eta;
+ Real C4 = x21 / L4; // 1
+ Real C5 = x32 / L5; //-1/sqrt(2);
+ Real C6 = x13 / L6; // 0
+ Real S4 = y21 / L4; // 0;
+ Real S5 = y32 / L5; // 1/sqrt(2);
+ Real S6 = y13 / L6; //-1;
+
+ Real N1 = 1 - xi - eta;
Real N2 = xi;
Real N3 = eta;
- Real P4 = 4*xi*(1-xi-eta);
- Real P5 = 4*xi*eta;
- Real P6 = 4*eta*(1-xi-eta);
+ Real P4 = 4 * xi * (1 - xi - eta);
+ Real P5 = 4 * xi * eta;
+ Real P6 = 4 * eta * (1 - xi - eta);
switch (id) {
case 0: { // N
N(0) = N1;
N(1) = N2;
N(2) = N3;
break;
}
case 1: { // Nwi2
- N(0) = -(1/8)*P4*L4*C4+(1/8)*P6*L6*C6;
- N(1) = -(1/8)*P5*L5*C5+(1/8)*P4*L4*C4;
- N(2) = -(1/8)*P6*L6*C6+(1/8)*P5*L5*C5;
+ N(0) = -(1 / 8) * P4 * L4 * C4 + (1 / 8) * P6 * L6 * C6;
+ N(1) = -(1 / 8) * P5 * L5 * C5 + (1 / 8) * P4 * L4 * C4;
+ N(2) = -(1 / 8) * P6 * L6 * C6 + (1 / 8) * P5 * L5 * C5;
break;
}
case 2: { // Nwi3
- N(0) = -(1/8)*P4*L4*S4+(1/8)*P6*L6*S6;
- N(1) = -(1/8)*P5*L5*S5+(1/8)*P4*L4*S4;
- N(2) = -(1/8)*P6*L6*S6+(1/8)*P5*L5*S5;
+ N(0) = -(1 / 8) * P4 * L4 * S4 + (1 / 8) * P6 * L6 * S6;
+ N(1) = -(1 / 8) * P5 * L5 * S5 + (1 / 8) * P4 * L4 * S4;
+ N(2) = -(1 / 8) * P6 * L6 * S6 + (1 / 8) * P5 * L5 * S5;
break;
- }
+ }
case 3: { // Nxi1
- N(0) = 3/(2*L4)*P4*C4-3/(2*L6)*P6*C6;
- N(1) = 3/(2*L5)*P5*C5-3/(2*L4)*P4*C4;
- N(2) = 3/(2*L6)*P6*C6-3/(2*L5)*P5*C5;
+ N(0) = 3 / (2 * L4) * P4 * C4 - 3 / (2 * L6) * P6 * C6;
+ N(1) = 3 / (2 * L5) * P5 * C5 - 3 / (2 * L4) * P4 * C4;
+ N(2) = 3 / (2 * L6) * P6 * C6 - 3 / (2 * L5) * P5 * C5;
break;
}
case 4: { // Nxi2
- N(0) = N1-(3./4.)*P4*C4*C4-(3./4.)*P6*C6*C6;
- N(1) = N2-(3./4.)*P5*C5*C5-(3./4.)*P4*C4*C4;
- N(2) = N3-(3./4.)*P6*C6*C6-(3./4.)*P5*C5*C5;
+ N(0) = N1 - (3. / 4.) * P4 * C4 * C4 - (3. / 4.) * P6 * C6 * C6;
+ N(1) = N2 - (3. / 4.) * P5 * C5 * C5 - (3. / 4.) * P4 * C4 * C4;
+ N(2) = N3 - (3. / 4.) * P6 * C6 * C6 - (3. / 4.) * P5 * C5 * C5;
break;
}
case 5: { // Nxi3
- N(0) = -(3./4.)*P4*C4*S4-(3./4.)*P6*C6*S6;
- N(1) = -(3./4.)*P5*C5*S5-(3./4.)*P4*C4*S4;
- N(2) = -(3./4.)*P6*C6*S6-(3./4.)*P5*C5*S5;
+ N(0) = -(3. / 4.) * P4 * C4 * S4 - (3. / 4.) * P6 * C6 * S6;
+ N(1) = -(3. / 4.) * P5 * C5 * S5 - (3. / 4.) * P4 * C4 * S4;
+ N(2) = -(3. / 4.) * P6 * C6 * S6 - (3. / 4.) * P5 * C5 * S5;
break;
}
- case 6: { // Nyi1
- N(0) = 3/(2*L4)*P4*S4-3/(2*L6)*P6*S6;
- N(1) = 3/(2*L5)*P5*S5-3/(2*L4)*P4*S4;
- N(2) = 3/(2*L6)*P6*S6-3/(2*L5)*P5*S5;
+ case 6: { // Nyi1
+ N(0) = 3 / (2 * L4) * P4 * S4 - 3 / (2 * L6) * P6 * S6;
+ N(1) = 3 / (2 * L5) * P5 * S5 - 3 / (2 * L4) * P4 * S4;
+ N(2) = 3 / (2 * L6) * P6 * S6 - 3 / (2 * L5) * P5 * S5;
break;
}
- case 7: { // Nyi2
- N(0) = -(3./4.)*P4*C4*S4-(3./4.)*P6*C6*S6;
- N(1) = -(3./4.)*P5*C5*S5-(3./4.)*P4*C4*S4;
- N(2) = -(3./4.)*P6*C6*S6-(3./4.)*P5*C5*S5;
+ case 7: { // Nyi2
+ N(0) = -(3. / 4.) * P4 * C4 * S4 - (3. / 4.) * P6 * C6 * S6;
+ N(1) = -(3. / 4.) * P5 * C5 * S5 - (3. / 4.) * P4 * C4 * S4;
+ N(2) = -(3. / 4.) * P6 * C6 * S6 - (3. / 4.) * P5 * C5 * S5;
break;
}
- case 8: { // Nyi3
- N(0) = N1-(3./4.)*P4*S4*S4-(3./4.)*P6*S6*S6;
- N(1) = N2-(3./4.)*P5*S5*S5-(3./4.)*P4*S4*S4;
- N(2) = N3-(3./4.)*P6*S6*S6-(3./4.)*P5*S5*S5;
+ case 8: { // Nyi3
+ N(0) = N1 - (3. / 4.) * P4 * S4 * S4 - (3. / 4.) * P6 * S6 * S6;
+ N(1) = N2 - (3. / 4.) * P5 * S5 * S5 - (3. / 4.) * P4 * S4 * S4;
+ N(2) = N3 - (3. / 4.) * P6 * S6 * S6 - (3. / 4.) * P5 * S5 * S5;
break;
}
}
}
-
+
/* -------------------------------------------------------------------------- */
template <>
-inline void
-InterpolationElement<_itp_kirchhoff_shell>::computeDNDS(const Vector<Real> & natural_coords,
- Matrix<Real> & dnds,
- const Matrix<Real> & projected_coord,
- UInt id) {
+inline void InterpolationElement<_itp_kirchhoff_shell>::computeDNDS(
+ const Vector<Real> & natural_coords, Matrix<Real> & dnds,
+ const Matrix<Real> & projected_coord, UInt id) {
-
// natural coordinate
- Real xi = natural_coords(0);
+ Real xi = natural_coords(0);
Real eta = natural_coords(1);
- // projected_coord (x1 x2 x3) (y1 y2 y3)
+ // projected_coord (x1 x2 x3) (y1 y2 y3)
-// donne juste pour pour le patch test 4_5_5 mais donne quelque changement de signe dans la matrice de rotation
+ // donne juste pour pour le patch test 4_5_5 mais donne quelque changement de
+ // signe dans la matrice de rotation
- Real x21=projected_coord(0,0)-projected_coord(0,1); //x1-x2
- Real x32=projected_coord(0,1)-projected_coord(0,2);
- Real x13=projected_coord(0,2)-projected_coord(0,0);
+ Real x21 = projected_coord(0, 0) - projected_coord(0, 1); // x1-x2
+ Real x32 = projected_coord(0, 1) - projected_coord(0, 2);
+ Real x13 = projected_coord(0, 2) - projected_coord(0, 0);
- Real y21=projected_coord(1,0)-projected_coord(1,1); //y1-y2
- Real y32=projected_coord(1,1)-projected_coord(1,2);
- Real y13=projected_coord(1,2)-projected_coord(1,0);
+ Real y21 = projected_coord(1, 0) - projected_coord(1, 1); // y1-y2
+ Real y32 = projected_coord(1, 1) - projected_coord(1, 2);
+ Real y13 = projected_coord(1, 2) - projected_coord(1, 0);
- // donne juste pour la matrice de rigidité... mais pas pour le patch test 4_5_5
+ // donne juste pour la matrice de rigidité... mais pas pour le patch test
+ // 4_5_5
-/* Real x21=projected_coord(0,1)-projected_coord(0,0);
- Real x32=projected_coord(0,2)-projected_coord(0,1);
- Real x13=projected_coord(0,0)-projected_coord(0,2);
+ /* Real x21=projected_coord(0,1)-projected_coord(0,0);
+ Real x32=projected_coord(0,2)-projected_coord(0,1);
+ Real x13=projected_coord(0,0)-projected_coord(0,2);
- Real y21=projected_coord(1,1)-projected_coord(1,0);
- Real y32=projected_coord(1,2)-projected_coord(1,1);
- Real y13=projected_coord(1,0)-projected_coord(1,2);*/
+ Real y21=projected_coord(1,1)-projected_coord(1,0);
+ Real y32=projected_coord(1,2)-projected_coord(1,1);
+ Real y13=projected_coord(1,0)-projected_coord(1,2);*/
// natural triangle side length
- Real L4=sqrt(x21*x21+y21*y21);
- Real L5=sqrt(x32*x32+y32*y32);
- Real L6=sqrt(x13*x13+y13*y13);
+ Real L4 = sqrt(x21 * x21 + y21 * y21);
+ Real L5 = sqrt(x32 * x32 + y32 * y32);
+ Real L6 = sqrt(x13 * x13 + y13 * y13);
// sinus and cosinus
- Real C4=x21/L4;
- Real C5=x32/L5;
- Real C6=x13/L6;
- Real S4=y21/L4;
- Real S5=y32/L5;
- Real S6=y13/L6;
-
-
+ Real C4 = x21 / L4;
+ Real C5 = x32 / L5;
+ Real C6 = x13 / L6;
+ Real S4 = y21 / L4;
+ Real S5 = y32 / L5;
+ Real S6 = y13 / L6;
+
Real dN1xi = -1;
Real dN2xi = 1;
Real dN3xi = 0;
Real dN1eta = -1;
Real dN2eta = 0;
Real dN3eta = 1;
- Real dP4xi = 4-8*xi-4*eta;
- Real dP5xi = 4*eta;
- Real dP6xi = -4*eta;
+ Real dP4xi = 4 - 8 * xi - 4 * eta;
+ Real dP5xi = 4 * eta;
+ Real dP6xi = -4 * eta;
- Real dP4eta = -4*xi;
- Real dP5eta = 4*xi;
- Real dP6eta = 4-4*xi-8*eta;
+ Real dP4eta = -4 * xi;
+ Real dP5eta = 4 * xi;
+ Real dP6eta = 4 - 4 * xi - 8 * eta;
switch (id) {
case 0: { // N'xi N'eta
- dnds(0,0) = dN1xi;
- dnds(0,1) = dN2xi;
- dnds(0,2) = dN3xi;
-
- dnds(1,0) = dN1eta;
- dnds(1,1) = dN2eta;
- dnds(1,2) = dN3eta;
- break;
+ dnds(0, 0) = dN1xi;
+ dnds(0, 1) = dN2xi;
+ dnds(0, 2) = dN3xi;
+
+ dnds(1, 0) = dN1eta;
+ dnds(1, 1) = dN2eta;
+ dnds(1, 2) = dN3eta;
+ break;
}
case 1: { // Nxi1'xi Nxi1'eta
- dnds(0,0) = 3/(2*L4)*dP4xi*C4-3/(2*L6)*dP6xi*C6;
- dnds(0,1) = 3/(2*L5)*dP5xi*C5-3/(2*L4)*dP4xi*C4;
- dnds(0,2) = 3/(2*L6)*dP6xi*C6-3/(2*L5)*dP5xi*C5;
+ dnds(0, 0) = 3 / (2 * L4) * dP4xi * C4 - 3 / (2 * L6) * dP6xi * C6;
+ dnds(0, 1) = 3 / (2 * L5) * dP5xi * C5 - 3 / (2 * L4) * dP4xi * C4;
+ dnds(0, 2) = 3 / (2 * L6) * dP6xi * C6 - 3 / (2 * L5) * dP5xi * C5;
- dnds(1,0) = 3/(2*L4)*dP4eta*C4-3/(2*L6)*dP6eta*C6;
- dnds(1,1) = 3/(2*L5)*dP5eta*C5-3/(2*L4)*dP4eta*C4;
- dnds(1,2) = 3/(2*L6)*dP6eta*C6-3/(2*L5)*dP5eta*C5;
+ dnds(1, 0) = 3 / (2 * L4) * dP4eta * C4 - 3 / (2 * L6) * dP6eta * C6;
+ dnds(1, 1) = 3 / (2 * L5) * dP5eta * C5 - 3 / (2 * L4) * dP4eta * C4;
+ dnds(1, 2) = 3 / (2 * L6) * dP6eta * C6 - 3 / (2 * L5) * dP5eta * C5;
break;
}
case 2: { // Nxi2'xi Nxi2'eta
- dnds(0,0) = -1-(3./4.)*dP4xi*C4*C4-(3./4.)*dP6xi*C6*C6;
- dnds(0,1) = 1-(3./4.)*dP5xi*C5*C5-(3./4.)*dP4xi*C4*C4;
- dnds(0,2) =-(3./4.)*dP6xi*C6*C6-(3./4.)*dP5xi*C5*C5;
-
- dnds(1,0) = -1-(3./4.)*dP4eta*C4*C4-(3./4.)*dP6eta*C6*C6;
- dnds(1,1) = -(3./4.)*dP5eta*C5*C5-(3./4.)*dP4eta*C4*C4;
- dnds(1,2) = 1-(3./4.)*dP6eta*C6*C6-(3./4.)*dP5eta*C5*C5;
+ dnds(0, 0) = -1 - (3. / 4.) * dP4xi * C4 * C4 - (3. / 4.) * dP6xi * C6 * C6;
+ dnds(0, 1) = 1 - (3. / 4.) * dP5xi * C5 * C5 - (3. / 4.) * dP4xi * C4 * C4;
+ dnds(0, 2) = -(3. / 4.) * dP6xi * C6 * C6 - (3. / 4.) * dP5xi * C5 * C5;
+
+ dnds(1, 0) =
+ -1 - (3. / 4.) * dP4eta * C4 * C4 - (3. / 4.) * dP6eta * C6 * C6;
+ dnds(1, 1) = -(3. / 4.) * dP5eta * C5 * C5 - (3. / 4.) * dP4eta * C4 * C4;
+ dnds(1, 2) =
+ 1 - (3. / 4.) * dP6eta * C6 * C6 - (3. / 4.) * dP5eta * C5 * C5;
break;
}
case 3: { // Nxi3'xi Nxi3'eta
- dnds(0,0) = -(3./4.)*dP4xi*C4*S4-(3./4.)*dP6xi*C6*S6;
- dnds(0,1) = -(3./4.)*dP5xi*C5*S5-(3./4.)*dP4xi*C4*S4;
- dnds(0,2) = -(3./4.)*dP6xi*C6*S6-(3./4.)*dP5xi*C5*S5;
+ dnds(0, 0) = -(3. / 4.) * dP4xi * C4 * S4 - (3. / 4.) * dP6xi * C6 * S6;
+ dnds(0, 1) = -(3. / 4.) * dP5xi * C5 * S5 - (3. / 4.) * dP4xi * C4 * S4;
+ dnds(0, 2) = -(3. / 4.) * dP6xi * C6 * S6 - (3. / 4.) * dP5xi * C5 * S5;
- dnds(1,0) = -(3./4.)*dP4eta*C4*S4-(3./4.)*dP6eta*C6*S6;
- dnds(1,1) = -(3./4.)*dP5eta*C5*S5-(3./4.)*dP4eta*C4*S4;
- dnds(1,2) = -(3./4.)*dP6eta*C6*S6-(3./4.)*dP5eta*C5*S5;
+ dnds(1, 0) = -(3. / 4.) * dP4eta * C4 * S4 - (3. / 4.) * dP6eta * C6 * S6;
+ dnds(1, 1) = -(3. / 4.) * dP5eta * C5 * S5 - (3. / 4.) * dP4eta * C4 * S4;
+ dnds(1, 2) = -(3. / 4.) * dP6eta * C6 * S6 - (3. / 4.) * dP5eta * C5 * S5;
break;
- }
+ }
case 4: { // Nyi1'xi Nyi1'eta
- dnds(0,0) = 3/(2*L4)*dP4xi*S4-3/(2*L6)*dP6xi*S6;
- dnds(0,1) = 3/(2*L5)*dP5xi*S5-3/(2*L4)*dP4xi*S4;
- dnds(0,2) = 3/(2*L6)*dP6xi*S6-3/(2*L5)*dP5xi*S5;
+ dnds(0, 0) = 3 / (2 * L4) * dP4xi * S4 - 3 / (2 * L6) * dP6xi * S6;
+ dnds(0, 1) = 3 / (2 * L5) * dP5xi * S5 - 3 / (2 * L4) * dP4xi * S4;
+ dnds(0, 2) = 3 / (2 * L6) * dP6xi * S6 - 3 / (2 * L5) * dP5xi * S5;
- dnds(1,0) = 3/(2*L4)*dP4eta*S4-3/(2*L6)*dP6eta*S6;
- dnds(1,1) = 3/(2*L5)*dP5eta*S5-3/(2*L4)*dP4eta*S4;
- dnds(1,2) = 3/(2*L6)*dP6eta*S6-3/(2*L5)*dP5eta*S5;
+ dnds(1, 0) = 3 / (2 * L4) * dP4eta * S4 - 3 / (2 * L6) * dP6eta * S6;
+ dnds(1, 1) = 3 / (2 * L5) * dP5eta * S5 - 3 / (2 * L4) * dP4eta * S4;
+ dnds(1, 2) = 3 / (2 * L6) * dP6eta * S6 - 3 / (2 * L5) * dP5eta * S5;
break;
}
- case 5: { // Nyi2'xi Nyi2'eta
- dnds(0,0) = -(3./4.)*dP4xi*C4*S4-(3./4.)*dP6xi*C6*S6;
- dnds(0,1) = -(3./4.)*dP5xi*C5*S5-(3./4.)*dP4xi*C4*S4;
- dnds(0,2) = -(3./4.)*dP6xi*C6*S6-(3./4.)*dP5xi*C5*S5;
-
- dnds(1,0) = -(3./4.)*dP4eta*C4*S4-(3./4.)*dP6eta*C6*S6;
- dnds(1,1) = -(3./4.)*dP5eta*C5*S5-(3./4.)*dP4eta*C4*S4;
- dnds(1,2) = -(3./4.)*dP6eta*C6*S6-(3./4.)*dP5eta*C5*S5;
+ case 5: { // Nyi2'xi Nyi2'eta
+ dnds(0, 0) = -(3. / 4.) * dP4xi * C4 * S4 - (3. / 4.) * dP6xi * C6 * S6;
+ dnds(0, 1) = -(3. / 4.) * dP5xi * C5 * S5 - (3. / 4.) * dP4xi * C4 * S4;
+ dnds(0, 2) = -(3. / 4.) * dP6xi * C6 * S6 - (3. / 4.) * dP5xi * C5 * S5;
+
+ dnds(1, 0) = -(3. / 4.) * dP4eta * C4 * S4 - (3. / 4.) * dP6eta * C6 * S6;
+ dnds(1, 1) = -(3. / 4.) * dP5eta * C5 * S5 - (3. / 4.) * dP4eta * C4 * S4;
+ dnds(1, 2) = -(3. / 4.) * dP6eta * C6 * S6 - (3. / 4.) * dP5eta * C5 * S5;
break;
}
- case 6: { // Nyi3'xi Nyi3'eta
- dnds(0,0) = dN1xi-(3./4.)*dP4xi*S4*S4-(3./4.)*dP6xi*S6*S6;
- dnds(0,1) = dN2xi-(3./4.)*dP5xi*S5*S5-(3./4.)*dP4xi*S4*S4;
- dnds(0,2) = dN3xi-(3./4.)*dP6xi*S6*S6-(3./4.)*dP5xi*S5*S5;
-
- dnds(1,0) = dN1eta-(3./4.)*dP4eta*S4*S4-(3./4.)*dP6eta*S6*S6;
- dnds(1,1) = dN2eta-(3./4.)*dP5eta*S5*S5-(3./4.)*dP4eta*S4*S4;
- dnds(1,2) = dN3eta-(3./4.)*dP6eta*S6*S6-(3./4.)*dP5eta*S5*S5;
+ case 6: { // Nyi3'xi Nyi3'eta
+ dnds(0, 0) =
+ dN1xi - (3. / 4.) * dP4xi * S4 * S4 - (3. / 4.) * dP6xi * S6 * S6;
+ dnds(0, 1) =
+ dN2xi - (3. / 4.) * dP5xi * S5 * S5 - (3. / 4.) * dP4xi * S4 * S4;
+ dnds(0, 2) =
+ dN3xi - (3. / 4.) * dP6xi * S6 * S6 - (3. / 4.) * dP5xi * S5 * S5;
+
+ dnds(1, 0) =
+ dN1eta - (3. / 4.) * dP4eta * S4 * S4 - (3. / 4.) * dP6eta * S6 * S6;
+ dnds(1, 1) =
+ dN2eta - (3. / 4.) * dP5eta * S5 * S5 - (3. / 4.) * dP4eta * S4 * S4;
+ dnds(1, 2) =
+ dN3eta - (3. / 4.) * dP6eta * S6 * S6 - (3. / 4.) * dP5eta * S5 * S5;
break;
}
}
}
diff --git a/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc b/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
index 40fbc9504..2de767bcb 100644
--- a/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
@@ -1,171 +1,172 @@
-/**
- * @file element_class_pentahedron_15_inline_impl.cc
- *
- * @author Sacha Laffely <sacha.laffely@epfl.ch>
- * @author Damien Scantamburlo <damien.scantamburlo@epfl.ch>
- *
- * @date creation: Wed Mar 19 2015
- *
- * @brief Specialization of the element_class class for the type _pentahedron_15
- *
- * @section LICENSE
- *
- * Copyright (©) 2010-2012, 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
- *
- * @verbatim
-
- /z
- |
- |
- | 1
- | /|\
- |/ | \
- 10 7 6
- / | \
- / | \
- 4 2--8--0
- | \ / /
- | \11 /
- 13 12 9----------/y
- | / \ /
- |/ \ /
- 5--14--3
- /
- /
- /
- \x
-
- x y z
-* N0 -1 1 0
-* N1 -1 0 1
-* N2 -1 0 0
-* N3 1 1 0
-* N4 1 0 1
-* N5 1 0 0
-* N6 -1 0.5 0.5
-* N7 -1 0 0.5
-* N8 -1 0.5 0
-* N9 0 1 0
-* N10 0 0 1
-* N11 0 0 0
-* N12 1 0.5 0.5
-* N13 1 0 0.5
-* N14 1 0.5 0
-
-*/
-
-/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_pentahedron_15,
- _gt_pentahedron_15,
- _itp_lagrange_pentahedron_15,
- _ek_regular,
- 3,
- _git_pentahedron,
- 2);
-
-AKANTU_DEFINE_SHAPE(_gt_pentahedron_15, _gst_prism);
-
-/* -------------------------------------------------------------------------- */
-template <>
-template <class vector_type>
-inline void
-InterpolationElement<_itp_lagrange_pentahedron_15>::computeShapes(const vector_type & c,
- vector_type & N) {
- // Shape Functions, Natural coordinates
- N( 0) = 0.5 * c(1) * (1 - c(0)) * (2 * c(1) - 2 - c(0));
- N( 1) = 0.5 * c(2) * (1 - c(0)) * (2 * c(2) - 2 - c(0));
- N( 2) = 0.5 * (c(0) - 1) * (1 - c(1) - c(2)) * (c(0) + 2 * c(1) + 2 * c(2));
- N( 3) = 0.5 * c(1) * (1 + c(0)) * (2 * c(1) - 2 + c(0));
- N( 4) = 0.5 * c(2) * (1 + c(0)) * (2 * c(2) - 2 + c(0));
- N( 5) = 0.5 * (-c(0) - 1) * (1 - c(1) - c(2)) * (-c(0) + 2 * c(1) + 2 * c(2));
- N( 6) = 2.0 * c(1) * c(2) * (1 - c(0));
- N( 7) = 2.0 * c(2) * (1 - c(1) - c(2)) * (1 - c(0));
- N( 8) = 2.0 * c(1) * (1 - c(0)) * (1 - c(1) - c(2));
- N( 9) = c(1) * (1 - c(0) * c(0));
- N(10) = c(2) * (1 - c(0) * c(0));
- N(11) = (1 - c(1) - c(2)) * (1 - c(0) * c(0));
- N(12) = 2.0 * c(1) * c(2) * (1 + c(0));
- N(13) = 2.0 * c(2) * (1 - c(1) - c(2)) * (1 + c(0));
- N(14) = 2.0 * c(1) * (1 - c(1) - c(2)) * (1 + c(0));
-}
-
-/* -------------------------------------------------------------------------- */
-template <>
-template <class vector_type, class matrix_type>
-inline void
-InterpolationElement<_itp_lagrange_pentahedron_15>::computeDNDS(const vector_type & c,
- matrix_type & dnds) {
- //ddx
- dnds(0, 0) = 0.5 * c(1) * (2 * c(0) - 2 * c(1) + 1);
- dnds(0, 1) = 0.5 * c(2) * (2 * c(0) - 2 * c(2) + 1);
- dnds(0, 2) = -0.5 * (2 * c(0) + 2 * c(1) + 2 * c(2) - 1) * (c(1) + c(2) -1);
- dnds(0, 3) = 0.5 * c(1) * (2 * c(0) + 2 * c(1) - 1);
- dnds(0, 4) = 0.5 * c(2) * (2 * c(0) + 2 * c(2) - 1);
- dnds(0, 5) = -0.5 * (c(1) + c(2) - 1) * (2 * c(0) - 2 * c(1) - 2 * c(2) + 1);
- dnds(0, 6) = -2.0 * c(1) * c(2);
- dnds(0, 7) = 2.0 * c(2) * (c(1) + c(2) - 1);
- dnds(0, 8) = 2.0 * c(1) * (c(1) + c(2) - 1);
- dnds(0, 9) = -2.0 * c(0) * c(1);
- dnds(0,10) = -2.0 * c(0) * c(2);
- dnds(0,11) = 2.0 * c(0) * (c(1) + c(2) - 1);
- dnds(0,12) = 2.0 * c(1) * c(2);
- dnds(0,13) = -2.0 * c(2) * (c(1) + c(2) - 1);
- dnds(0,14) = -2.0 * c(1) * (c(1) + c(2) - 1);
-
- //ddy
- dnds(1, 0) = -0.5 * (c(0) - 1) * (4 * c(1) - c(0) - 2);
- dnds(1, 1) = 0.0;
- dnds(1, 2) = -0.5 * (c(0) - 1) * (4 * c(1) + c(0) + 2 * (2 * c(2) - 1));
- dnds(1, 3) = 0.5 * (c(0) + 1) * (4 * c(1) + c(0) - 2);
- dnds(1, 4) = 0.0;
- dnds(1, 5) = 0.5 * (c(0) + 1) * (4 * c(1) - c(0) + 2 * (2 * c(2) - 1));
- dnds(1, 6) = -2.0 * (c(0) - 1) * c(2);
- dnds(1, 7) = 2.0 * c(2) * (c(0) - 1);
- dnds(1, 8) = 2.0 * (2 * c(1) + c(2) - 1) * (c(0) - 1);
- dnds(1, 9) = -(c(0) * c(0) - 1);
- dnds(1,10) = 0.0;
- dnds(1,11) = (c(0) * c(0) - 1);
- dnds(1,12) = 2.0 * c(2) * (c(0) + 1);
- dnds(1,13) = -2.0 * c(2) * (c(0) + 1);
- dnds(1,14) = -2.0 * (2 * c(1) + c(2) - 1) * (c(0) + 1);
-
- //ddz
- dnds(2, 0) = 0.0;
- dnds(2, 1) = -0.5 * (c(0) - 1) * (4 * c(2) - c(0) - 2);
- dnds(2, 2) = -0.5 * (c(0) - 1) * (4 * c(2) + c(0) + 2 * (2 * c(1) - 1));
- dnds(2, 3) = 0.0;
- dnds(2, 4) = 0.5 * (c(0) + 1) * (4 * c(2) + c(0) - 2);
- dnds(2, 5) = 0.5 * (c(0) + 1) * (4 * c(2) - c(0) + 2 * (2 * c(1) - 1));
- dnds(2, 6) = -2.0 * (c(0) - 1) * c(1);
- dnds(2, 7) = 2.0 * (c(0) - 1) * (2 * c(2) + c(1) - 1);
- dnds(2, 8) = 2.0 * c(1) * (c(0) - 1);
- dnds(2, 9) = 0.0;
- dnds(2,10) = -(c(0) * c(0) - 1);
- dnds(2,11) = (c(0) * c(0) - 1);
- dnds(2,12) = 2.0 * (c(0) + 1) * c(1);
- dnds(2,13) = -2.0 * (c(0) + 1) * (2 * c(2) + c(1) - 1);
- dnds(2,14) = -2.0 * (c(0) + 1) * c(1);
-}
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline Real
-GeometricalElement<_gt_pentahedron_15>::getInradius(const Matrix<Real> & coord) {
- return GeometricalElement<_gt_pentahedron_6>::getInradius(coord);
-}
+/**
+ * @file element_class_pentahedron_15_inline_impl.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Sacha Laffely <sacha.laffely@epfl.ch>
+ * @author Damien Scantamburlo <damien.scantamburlo@epfl.ch>
+ *
+ * @date creation: Tue Mar 31 2015
+ * @date last modification: Wed Sep 16 2015
+ *
+ * @brief Specialization of the element_class class for the type _pentahedron_15
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ * @section DESCRIPTION
+ *
+ * @verbatim
+ z
+ ^
+ |
+ |
+ | 1
+ | /|\
+ |/ | \
+ 10 7 6
+ / | \
+ / | \
+ 4 2--8--0
+ | \ / /
+ | \11 /
+ 13 12 9---------->y
+ | / \ /
+ |/ \ /
+ 5--14--3
+ /
+ /
+ /
+ v
+ x
+ x y z
+* N0 -1 1 0
+* N1 -1 0 1
+* N2 -1 0 0
+* N3 1 1 0
+* N4 1 0 1
+* N5 1 0 0
+* N6 -1 0.5 0.5
+* N7 -1 0 0.5
+* N8 -1 0.5 0
+* N9 0 1 0
+* N10 0 0 1
+* N11 0 0 0
+* N12 1 0.5 0.5
+* N13 1 0 0.5
+* N14 1 0.5 0
+ */
+
+/* -------------------------------------------------------------------------- */
+AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_pentahedron_15,
+ _gt_pentahedron_15,
+ _itp_lagrange_pentahedron_15,
+ _ek_regular,
+ 3,
+ _git_pentahedron,
+ 2);
+
+AKANTU_DEFINE_SHAPE(_gt_pentahedron_15, _gst_prism);
+
+/* -------------------------------------------------------------------------- */
+template <>
+template <class vector_type>
+inline void
+InterpolationElement<_itp_lagrange_pentahedron_15>::computeShapes(const vector_type & c,
+ vector_type & N) {
+ // Shape Functions, Natural coordinates
+ N( 0) = 0.5 * c(1) * (1 - c(0)) * (2 * c(1) - 2 - c(0));
+ N( 1) = 0.5 * c(2) * (1 - c(0)) * (2 * c(2) - 2 - c(0));
+ N( 2) = 0.5 * (c(0) - 1) * (1 - c(1) - c(2)) * (c(0) + 2 * c(1) + 2 * c(2));
+ N( 3) = 0.5 * c(1) * (1 + c(0)) * (2 * c(1) - 2 + c(0));
+ N( 4) = 0.5 * c(2) * (1 + c(0)) * (2 * c(2) - 2 + c(0));
+ N( 5) = 0.5 * (-c(0) - 1) * (1 - c(1) - c(2)) * (-c(0) + 2 * c(1) + 2 * c(2));
+ N( 6) = 2.0 * c(1) * c(2) * (1 - c(0));
+ N( 7) = 2.0 * c(2) * (1 - c(1) - c(2)) * (1 - c(0));
+ N( 8) = 2.0 * c(1) * (1 - c(0)) * (1 - c(1) - c(2));
+ N( 9) = c(1) * (1 - c(0) * c(0));
+ N(10) = c(2) * (1 - c(0) * c(0));
+ N(11) = (1 - c(1) - c(2)) * (1 - c(0) * c(0));
+ N(12) = 2.0 * c(1) * c(2) * (1 + c(0));
+ N(13) = 2.0 * c(2) * (1 - c(1) - c(2)) * (1 + c(0));
+ N(14) = 2.0 * c(1) * (1 - c(1) - c(2)) * (1 + c(0));
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+template <class vector_type, class matrix_type>
+inline void
+InterpolationElement<_itp_lagrange_pentahedron_15>::computeDNDS(const vector_type & c,
+ matrix_type & dnds) {
+ //ddx
+ dnds(0, 0) = 0.5 * c(1) * (2 * c(0) - 2 * c(1) + 1);
+ dnds(0, 1) = 0.5 * c(2) * (2 * c(0) - 2 * c(2) + 1);
+ dnds(0, 2) = -0.5 * (2 * c(0) + 2 * c(1) + 2 * c(2) - 1) * (c(1) + c(2) -1);
+ dnds(0, 3) = 0.5 * c(1) * (2 * c(0) + 2 * c(1) - 1);
+ dnds(0, 4) = 0.5 * c(2) * (2 * c(0) + 2 * c(2) - 1);
+ dnds(0, 5) = -0.5 * (c(1) + c(2) - 1) * (2 * c(0) - 2 * c(1) - 2 * c(2) + 1);
+ dnds(0, 6) = -2.0 * c(1) * c(2);
+ dnds(0, 7) = 2.0 * c(2) * (c(1) + c(2) - 1);
+ dnds(0, 8) = 2.0 * c(1) * (c(1) + c(2) - 1);
+ dnds(0, 9) = -2.0 * c(0) * c(1);
+ dnds(0,10) = -2.0 * c(0) * c(2);
+ dnds(0,11) = 2.0 * c(0) * (c(1) + c(2) - 1);
+ dnds(0,12) = 2.0 * c(1) * c(2);
+ dnds(0,13) = -2.0 * c(2) * (c(1) + c(2) - 1);
+ dnds(0,14) = -2.0 * c(1) * (c(1) + c(2) - 1);
+
+ //ddy
+ dnds(1, 0) = -0.5 * (c(0) - 1) * (4 * c(1) - c(0) - 2);
+ dnds(1, 1) = 0.0;
+ dnds(1, 2) = -0.5 * (c(0) - 1) * (4 * c(1) + c(0) + 2 * (2 * c(2) - 1));
+ dnds(1, 3) = 0.5 * (c(0) + 1) * (4 * c(1) + c(0) - 2);
+ dnds(1, 4) = 0.0;
+ dnds(1, 5) = 0.5 * (c(0) + 1) * (4 * c(1) - c(0) + 2 * (2 * c(2) - 1));
+ dnds(1, 6) = -2.0 * (c(0) - 1) * c(2);
+ dnds(1, 7) = 2.0 * c(2) * (c(0) - 1);
+ dnds(1, 8) = 2.0 * (2 * c(1) + c(2) - 1) * (c(0) - 1);
+ dnds(1, 9) = -(c(0) * c(0) - 1);
+ dnds(1,10) = 0.0;
+ dnds(1,11) = (c(0) * c(0) - 1);
+ dnds(1,12) = 2.0 * c(2) * (c(0) + 1);
+ dnds(1,13) = -2.0 * c(2) * (c(0) + 1);
+ dnds(1,14) = -2.0 * (2 * c(1) + c(2) - 1) * (c(0) + 1);
+
+ //ddz
+ dnds(2, 0) = 0.0;
+ dnds(2, 1) = -0.5 * (c(0) - 1) * (4 * c(2) - c(0) - 2);
+ dnds(2, 2) = -0.5 * (c(0) - 1) * (4 * c(2) + c(0) + 2 * (2 * c(1) - 1));
+ dnds(2, 3) = 0.0;
+ dnds(2, 4) = 0.5 * (c(0) + 1) * (4 * c(2) + c(0) - 2);
+ dnds(2, 5) = 0.5 * (c(0) + 1) * (4 * c(2) - c(0) + 2 * (2 * c(1) - 1));
+ dnds(2, 6) = -2.0 * (c(0) - 1) * c(1);
+ dnds(2, 7) = 2.0 * (c(0) - 1) * (2 * c(2) + c(1) - 1);
+ dnds(2, 8) = 2.0 * c(1) * (c(0) - 1);
+ dnds(2, 9) = 0.0;
+ dnds(2,10) = -(c(0) * c(0) - 1);
+ dnds(2,11) = (c(0) * c(0) - 1);
+ dnds(2,12) = 2.0 * (c(0) + 1) * c(1);
+ dnds(2,13) = -2.0 * (c(0) + 1) * (2 * c(2) + c(1) - 1);
+ dnds(2,14) = -2.0 * (c(0) + 1) * c(1);
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
+inline Real
+GeometricalElement<_gt_pentahedron_15>::getInradius(const Matrix<Real> & coord) {
+ return GeometricalElement<_gt_pentahedron_6>::getInradius(coord);
+}
diff --git a/src/fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc b/src/fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
index e279cb18c..60c423e1c 100644
--- a/src/fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
@@ -1,136 +1,136 @@
/**
* @file element_class_pentahedron_6_inline_impl.cc
*
* @author Marion Estelle Chambart <mchambart@stucky.ch>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Thomas Menouillard <tmenouillard@stucky.ch>
*
- * @date creation: Wed Jun 12 2013
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Mon Mar 14 2011
+ * @date last modification: Tue Sep 01 2015
*
* @brief Specialization of the element_class class for the type _pentahedron_6
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
-
/z
|
|
| 1
| /|\
|/ | \
/ | \
/ | \
/ | \
4 2-----0
| \ / /
| \/ /
| \ /----------/y
| / \ /
|/ \ /
5---.--3
/
/
/
\x
-
x y z
* N0 -1 1 0
* N1 -1 0 1
* N2 -1 0 0
* N3 1 1 0
* N4 1 0 1
* N5 1 0 0
-*/
+ */
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_pentahedron_6,
_gt_pentahedron_6,
_itp_lagrange_pentahedron_6,
_ek_regular,
3,
_git_pentahedron,
1);
AKANTU_DEFINE_SHAPE(_gt_pentahedron_6, _gst_prism);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_pentahedron_6>::computeShapes(const vector_type & c,
vector_type & N) {
/// Natural coordinates
N(0) = 0.5*c(1)*(1-c(0)); // N1(q)
N(1) = 0.5*c(2)*(1-c(0)); // N2(q)
N(2) = 0.5*(1-c(1)-c(2))*(1-c(0)); // N3(q)
N(3) = 0.5*c(1)*(1+c(0)); // N4(q)
N(4) = 0.5*c(2)*(1+c(0)); // N5(q)
N(5) = 0.5*(1-c(1)-c(2))*(1+c(0)); // N6(q)
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_pentahedron_6>::computeDNDS(const vector_type & c,
matrix_type & dnds) {
dnds(0, 0) = -0.5*c(1);
dnds(0, 1) = -0.5*c(2);
dnds(0, 2) = -0.5*(1-c(1)-c(2));
dnds(0, 3) = 0.5*c(1);
dnds(0, 4) = 0.5*c(2);
dnds(0, 5) = 0.5*(1-c(1)-c(2));
dnds(1, 0) = 0.5*(1-c(0));
dnds(1, 1) = 0.0;
dnds(1, 2) = -0.5*(1-c(0));
dnds(1, 3) = 0.5*(1+c(0));
dnds(1, 4) = 0.0;
dnds(1, 5) = -0.5*(1+c(0));
dnds(2, 0) = 0.0;
dnds(2, 1) = 0.5*(1-c(0));
dnds(2, 2) = -0.5*(1-c(0));
dnds(2, 3) = 0.0;
dnds(2, 4) = 0.5*(1+c(0));
dnds(2, 5) = -0.5*(1+c(0));
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_pentahedron_6>::getInradius(const Matrix<Real> & coord) {
Vector<Real> u0 = coord(0);
Vector<Real> u1 = coord(1);
Vector<Real> u2 = coord(2);
Vector<Real> u3 = coord(3);
Real a = u0.distance(u1);
Real b = u1.distance(u2);
Real c = u2.distance(u3);
Real d = u3.distance(u0);
Real s = (a+b+c)/2;
Real A = std::sqrt(s*(s-a)*(s-b)*(s-c));
Real ra = 2*s/A;
Real p = std::min(ra, d);
return p;
}
diff --git a/src/fe_engine/element_classes/element_class_point_1_inline_impl.cc b/src/fe_engine/element_classes/element_class_point_1_inline_impl.cc
index 12af14517..4cbdf3e8d 100644
--- a/src/fe_engine/element_classes/element_class_point_1_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_point_1_inline_impl.cc
@@ -1,87 +1,88 @@
/**
* @file element_class_point_1_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _point_1
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
x
(0)
@endverbatim
*
* @subsection shapes Shape functions
* @f{eqnarray*}{
* N1 &=& 1
* @f}
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* q_0 &=& 0
* @f}
*/
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_point_1,
_gt_point,
_itp_lagrange_point_1,
_ek_regular,
0,
_git_point,
1);
AKANTU_DEFINE_SHAPE(_gt_point, _gst_point);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_point_1>::computeShapes(__attribute__ ((unused)) const vector_type & natural_coords,
vector_type & N) {
N(0) = 1; /// N1(q_0)
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_point_1>::computeDNDS(__attribute__ ((unused)) const vector_type & natural_coords,
__attribute__ ((unused)) matrix_type & dnds) {}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_lagrange_point_1>::computeSpecialJacobian(__attribute__ ((unused)) const Matrix<Real> & J,
Real & jac){
jac = 0.;
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_point>::getInradius(const Matrix<Real> & coord) {
return 0.;
}
diff --git a/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc b/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
index 29e8cef18..2e33b9542 100644
--- a/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
@@ -1,151 +1,152 @@
/**
* @file element_class_quadrangle_4_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Mon Dec 08 2014
*
* @brief Specialization of the element_class class for the type _quadrangle_4
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
\eta
^
(-1,1) | (1,1)
x---------x
| | |
| | |
--|---------|-----> \xi
| | |
| | |
x---------x
(-1,-1) | (1,-1)
@endverbatim
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{lll}
* N1 = (1 - \xi) (1 - \eta) / 4
* & \frac{\partial N1}{\partial \xi} = - (1 - \eta) / 4
* & \frac{\partial N1}{\partial \eta} = - (1 - \xi) / 4 \\
* N2 = (1 + \xi) (1 - \eta) / 4 \\
* & \frac{\partial N2}{\partial \xi} = (1 - \eta) / 4
* & \frac{\partial N2}{\partial \eta} = - (1 + \xi) / 4 \\
* N3 = (1 + \xi) (1 + \eta) / 4 \\
* & \frac{\partial N3}{\partial \xi} = (1 + \eta) / 4
* & \frac{\partial N3}{\partial \eta} = (1 + \xi) / 4 \\
* N4 = (1 - \xi) (1 + \eta) / 4
* & \frac{\partial N4}{\partial \xi} = - (1 + \eta) / 4
* & \frac{\partial N4}{\partial \eta} = (1 - \xi) / 4 \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 0 \qquad \eta_{q0} = 0
* @f}
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_quadrangle_4, _gt_quadrangle_4, _itp_lagrange_quadrangle_4, _ek_regular, 2,
_git_segment, 2);
AKANTU_DEFINE_SHAPE(_gt_quadrangle_4, _gst_square);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_quadrangle_4>::computeShapes(const vector_type & c,
vector_type & N) {
N(0) = 1./4. * (1. - c(0)) * (1. - c(1)); /// N1(q_0)
N(1) = 1./4. * (1. + c(0)) * (1. - c(1)); /// N2(q_0)
N(2) = 1./4. * (1. + c(0)) * (1. + c(1)); /// N3(q_0)
N(3) = 1./4. * (1. - c(0)) * (1. + c(1)); /// N4(q_0)
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_quadrangle_4>::computeDNDS(const vector_type & c,
matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccc}
* \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi}
* & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial \xi}\\
* \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta}
* & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial \eta}
* \end{array}
* \right)
* @f]
*/
dnds(0, 0) = - 1./4. * (1. - c(1));
dnds(0, 1) = 1./4. * (1. - c(1));
dnds(0, 2) = 1./4. * (1. + c(1));
dnds(0, 3) = - 1./4. * (1. + c(1));
dnds(1, 0) = - 1./4. * (1. - c(0));
dnds(1, 1) = - 1./4. * (1. + c(0));
dnds(1, 2) = 1./4. * (1. + c(0));
dnds(1, 3) = 1./4. * (1. - c(0));
}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_lagrange_quadrangle_4>::computeSpecialJacobian(const Matrix<Real> & J,
Real & jac){
Vector<Real> vprod(J.cols());
Matrix<Real> Jt(J.transpose(), true);
vprod.crossProduct(Jt(0), Jt(1));
jac = vprod.norm();
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_quadrangle_4>::getInradius(const Matrix<Real> & coord) {
Vector<Real> u0 = coord(0);
Vector<Real> u1 = coord(1);
Vector<Real> u2 = coord(2);
Vector<Real> u3 = coord(3);
Real a = u0.distance(u1);
Real b = u1.distance(u2);
Real c = u2.distance(u3);
Real d = u3.distance(u0);
// Real septimetre = (a + b + c + d) / 2.;
// Real p = Math::distance_2d(coord + 0, coord + 4);
// Real q = Math::distance_2d(coord + 2, coord + 6);
// Real area = sqrt(4*(p*p * q*q) - (a*a + b*b + c*c + d*d)*(a*a + c*c - b*b - d*d)) / 4.;
// Real h = sqrt(area); // to get a length
// Real h = area / septimetre; // formula of inradius for circumscritable quadrelateral
Real h = std::min(a, std::min(b, std::min(c, d)));
return h;
}
diff --git a/src/fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc b/src/fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
index 2dad01b1d..6f6e708a4 100644
--- a/src/fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
@@ -1,188 +1,189 @@
/**
* @file element_class_quadrangle_8_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed May 18 2011
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Tue Apr 07 2015
*
* @brief Specialization of the ElementClass for the _quadrangle_8
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
\eta
^
|
(-1,1) (0,1) (1,1)
x-------x-------x
| | |
| | |
| | |
(-1,0)| | |(1,0)
----x---------------X-----> \xi
| | |
| | |
| | |
| | |
x-------x-------x
(-1,-1) (0,-1) (1,-1)
|
@endverbatim
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{lll}
* N1 = (1 - \xi) (1 - \eta)(- 1 - \xi - \eta) / 4
* & \frac{\partial N1}{\partial \xi} = (1 - \eta)(2 \xi + \eta) / 4
* & \frac{\partial N1}{\partial \eta} = (1 - \xi)(\xi + 2 \eta) / 4 \\
* N2 = (1 + \xi) (1 - \eta)(- 1 + \xi - \eta) / 4 \\
* & \frac{\partial N2}{\partial \xi} = (1 - \eta)(2 \xi - \eta) / 4
* & \frac{\partial N2}{\partial \eta} = - (1 + \xi)(\xi - 2 \eta) / 4 \\
* N3 = (1 + \xi) (1 + \eta)(- 1 + \xi + \eta) / 4 \\
* & \frac{\partial N3}{\partial \xi} = (1 + \eta)(2 \xi + \eta) / 4
* & \frac{\partial N3}{\partial \eta} = (1 + \xi)(\xi + 2 \eta) / 4 \\
* N4 = (1 - \xi) (1 + \eta)(- 1 - \xi + \eta) / 4
* & \frac{\partial N4}{\partial \xi} = (1 + \eta)(2 \xi - \eta) / 4
* & \frac{\partial N4}{\partial \eta} = - (1 - \xi)(\xi - 2 \eta) / 4 \\
* N5 = (1 - \xi^2) (1 - \eta) / 2
* & \frac{\partial N1}{\partial \xi} = - \xi (1 - \eta)
* & \frac{\partial N1}{\partial \eta} = - (1 - \xi^2) / 2 \\
* N6 = (1 + \xi) (1 - \eta^2) / 2 \\
* & \frac{\partial N2}{\partial \xi} = (1 - \eta^2) / 2
* & \frac{\partial N2}{\partial \eta} = - \eta (1 + \xi) \\
* N7 = (1 - \xi^2) (1 + \eta) / 2 \\
* & \frac{\partial N3}{\partial \xi} = - \xi (1 + \eta)
* & \frac{\partial N3}{\partial \eta} = (1 - \xi^2) / 2 \\
* N8 = (1 - \xi) (1 - \eta^2) / 2
* & \frac{\partial N4}{\partial \xi} = - (1 - \eta^2) / 2
* & \frac{\partial N4}{\partial \eta} = - \eta (1 - \xi) \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 0 \qquad \eta_{q0} = 0
* @f}
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_quadrangle_8, _gt_quadrangle_8, _itp_serendip_quadrangle_8, _ek_regular, 2,
_git_segment, 3);
AKANTU_DEFINE_SHAPE(_gt_quadrangle_8, _gst_square);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_serendip_quadrangle_8>::computeShapes(const vector_type & c,
vector_type & N) {
/// Natural coordinates
const Real xi = c(0);
const Real eta = c(1);
N(0) = .25 * (1 - xi) * (1 - eta) * (- 1 - xi - eta);
N(1) = .25 * (1 + xi) * (1 - eta) * (- 1 + xi - eta);
N(2) = .25 * (1 + xi) * (1 + eta) * (- 1 + xi + eta);
N(3) = .25 * (1 - xi) * (1 + eta) * (- 1 - xi + eta);
N(4) = .5 * (1 - xi * xi) * (1 - eta );
N(5) = .5 * (1 + xi ) * (1 - eta * eta);
N(6) = .5 * (1 - xi * xi) * (1 + eta );
N(7) = .5 * (1 - xi ) * (1 - eta * eta);
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_serendip_quadrangle_8>::computeDNDS(const vector_type & c,
matrix_type & dnds) {
const Real xi = c(0);
const Real eta = c(1);
/// dN/dxi
dnds(0, 0) = .25 * (1 - eta) * (2 * xi + eta);
dnds(0, 1) = .25 * (1 - eta) * (2 * xi - eta);
dnds(0, 2) = .25 * (1 + eta) * (2 * xi + eta);
dnds(0, 3) = .25 * (1 + eta) * (2 * xi - eta);
dnds(0, 4) = - xi * (1 - eta);
dnds(0, 5) = .5 * (1 - eta * eta);
dnds(0, 6) = - xi * (1 + eta);
dnds(0, 7) = - .5 * (1 - eta * eta);
/// dN/deta
dnds(1, 0) = .25 * (1 - xi) * (2 * eta + xi);
dnds(1, 1) = .25 * (1 + xi) * (2 * eta - xi);
dnds(1, 2) = .25 * (1 + xi) * (2 * eta + xi);
dnds(1, 3) = .25 * (1 - xi) * (2 * eta - xi);
dnds(1, 4) = - .5 * (1 - xi * xi);
dnds(1, 5) = - eta * (1 + xi);
dnds(1, 6) = .5 * (1 - xi * xi);
dnds(1, 7) = - eta * (1 - xi);
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_quadrangle_8>::getInradius(const Matrix<Real> & coord) {
Real a, b, h;
Vector<Real> u0 = coord(0);
Vector<Real> u1 = coord(1);
Vector<Real> u2 = coord(2);
Vector<Real> u3 = coord(3);
Vector<Real> u4 = coord(4);
Vector<Real> u5 = coord(5);
Vector<Real> u6 = coord(6);
Vector<Real> u7 = coord(7);
a = u0.distance(u4);
b = u4.distance(u1);
h = std::min(a, b);
a = u1.distance(u5);
b = u5.distance(u2);
h = std::min(h, std::min(a, b));
a = u2.distance(u6);
b = u6.distance(u3);
h = std::min(h, std::min(a, b));
a = u3.distance(u7);
b = u7.distance(u0);
h = std::min(h, std::min(a, b));
return h;
}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_serendip_quadrangle_8>::computeSpecialJacobian(const Matrix<Real> & J,
Real & jac){
Vector<Real> vprod(J.cols());
Matrix<Real> Jt(J.transpose(), true);
vprod.crossProduct(Jt(0), Jt(1));
jac = vprod.norm();
}
diff --git a/src/fe_engine/element_classes/element_class_segment_2_inline_impl.cc b/src/fe_engine/element_classes/element_class_segment_2_inline_impl.cc
index 40f5cf05e..90e9056de 100644
--- a/src/fe_engine/element_classes/element_class_segment_2_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_segment_2_inline_impl.cc
@@ -1,106 +1,107 @@
/**
* @file element_class_segment_2_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 16 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _segment_2
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
q
--x--------|--------x---> x
-1 0 1
@endverbatim
*
* @subsection shapes Shape functions
* @f{eqnarray*}{
* w_1(x) &=& 1/2(1 - x) \\
* w_2(x) &=& 1/2(1 + x)
* @f}
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* x_{q} &=& 0
* @f}
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_segment_2, _gt_segment_2, _itp_lagrange_segment_2, _ek_regular, 1,
_git_segment, 1);
AKANTU_DEFINE_SHAPE(_gt_segment_2, _gst_square);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_segment_2>::computeShapes(const vector_type & natural_coords,
vector_type & N) {
/// natural coordinate
Real c = natural_coords(0);
/// shape functions
N(0) = 0.5*(1-c);
N(1) = 0.5*(1+c);
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_segment_2>::computeDNDS(__attribute__ ((unused)) const vector_type & natural_coords,
matrix_type & dnds){
/// dN1/de
dnds(0, 0) = - .5;
/// dN2/de
dnds(0, 1) = .5;
}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_lagrange_segment_2>::computeSpecialJacobian(const Matrix<Real> & dxds,
Real & jac) {
jac = dxds.norm<L_2>();
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_segment_2>::getInradius(const Matrix<Real> & coord) {
return std::abs(coord(0, 0) - coord(0, 1));
}
// /* -------------------------------------------------------------------------- */
// template<> inline bool ElementClass<_segment_2>::contains(const Vector<Real> & natural_coords) {
// if (natural_coords(0) < -1.) return false;
// if (natural_coords(0) > 1.) return false;
// return true;
// }
/* -------------------------------------------------------------------------- */
diff --git a/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc b/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc
index 12948d70b..3f05b4839 100644
--- a/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc
@@ -1,107 +1,108 @@
/**
* @file element_class_segment_3_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 16 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _segment_3
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
-1 0 1
-----x---------x---------x-----> x
1 3 2
@endverbatim
*
* @subsection coords Nodes coordinates
*
* @f[
* \begin{array}{lll}
* x_{1} = -1 & x_{2} = 1 & x_{3} = 0
* \end{array}
* @f]
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{ll}
* w_1(x) = \frac{x}{2}(x - 1) & w'_1(x) = x - \frac{1}{2}\\
* w_2(x) = \frac{x}{2}(x + 1) & w'_2(x) = x + \frac{1}{2}\\
* w_3(x) = 1-x^2 & w'_3(x) = -2x
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f[
* \begin{array}{ll}
* x_{q1} = -1/\sqrt{3} & x_{q2} = 1/\sqrt{3}
* \end{array}
* @f]
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_segment_3, _gt_segment_3, _itp_lagrange_segment_3, _ek_regular, 1,
_git_segment, 2);
AKANTU_DEFINE_SHAPE(_gt_segment_3, _gst_square);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_segment_3>::computeShapes(const vector_type & natural_coords,
vector_type & N) {
Real c = natural_coords(0);
N(0) = (c - 1) * c / 2;
N(1) = (c + 1) * c / 2;
N(2) = 1 - c * c;
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_segment_3>::computeDNDS(const vector_type & natural_coords,
matrix_type & dnds){
Real c = natural_coords(0);
dnds(0, 0) = c - .5;
dnds(0, 1) = c + .5;
dnds(0, 2) = -2 * c;
}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_lagrange_segment_3>::computeSpecialJacobian(const Matrix<Real> & dxds,
Real & jac) {
jac = Math::norm2(dxds.storage());
}
/* -------------------------------------------------------------------------- */
template<> inline Real
GeometricalElement<_gt_segment_3>::getInradius(const Matrix<Real> & coord) {
Real dist1 = std::abs(coord(0, 0) - coord(0, 1));
Real dist2 = std::abs(coord(0, 1) - coord(0, 2));
return std::min(dist1, dist2);
}
diff --git a/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc b/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
index 2e74ad1b8..7ea9c69cd 100644
--- a/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
@@ -1,264 +1,265 @@
/**
* @file element_class_tetrahedron_10_inline_impl.cc
*
* @author Peter Spijker <peter.spijker@epfl.ch>
*
* @date creation: Fri Jul 16 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _tetrahedron_10
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
\zeta
^
|
(0,0,1)
x
|` .
| ` .
| ` .
| ` . (0,0.5,0.5)
| ` x.
| q4 o ` . \eta
| ` . -,
(0,0,0.5) x ` x (0.5,0,0.5) -
| ` x-(0,1,0)
| q3 o` - '
| (0,0.5,0) - ` '
| x- ` x (0.5,0.5,0)
| q1 o - o q2` '
| - ` '
| - ` '
x---------------x--------------` x-----> \xi
(0,0,0) (0.5,0,0) (1,0,0)
@endverbatim
*
* @subsection coords Nodes coordinates
*
* @f[
* \begin{array}{lll}
* \xi_{0} = 0 & \eta_{0} = 0 & \zeta_{0} = 0 \\
* \xi_{1} = 1 & \eta_{1} = 0 & \zeta_{1} = 0 \\
* \xi_{2} = 0 & \eta_{2} = 1 & \zeta_{2} = 0 \\
* \xi_{3} = 0 & \eta_{3} = 0 & \zeta_{3} = 1 \\
* \xi_{4} = 1/2 & \eta_{4} = 0 & \zeta_{4} = 0 \\
* \xi_{5} = 1/2 & \eta_{5} = 1/2 & \zeta_{5} = 0 \\
* \xi_{6} = 0 & \eta_{6} = 1/2 & \zeta_{6} = 0 \\
* \xi_{7} = 0 & \eta_{7} = 0 & \zeta_{7} = 1/2 \\
* \xi_{8} = 1/2 & \eta_{8} = 0 & \zeta_{8} = 1/2 \\
* \xi_{9} = 0 & \eta_{9} = 1/2 & \zeta_{9} = 1/2
* \end{array}
* @f]
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{llll}
* N1 = (1 - \xi - \eta - \zeta) (1 - 2 \xi - 2 \eta - 2 \zeta)
* & \frac{\partial N1}{\partial \xi} = 4 \xi + 4 \eta + 4 \zeta - 3
* & \frac{\partial N1}{\partial \eta} = 4 \xi + 4 \eta + 4 \zeta - 3
* & \frac{\partial N1}{\partial \zeta} = 4 \xi + 4 \eta + 4 \zeta - 3 \\
* N2 = \xi (2 \xi - 1)
* & \frac{\partial N2}{\partial \xi} = 4 \xi - 1
* & \frac{\partial N2}{\partial \eta} = 0
* & \frac{\partial N2}{\partial \zeta} = 0 \\
* N3 = \eta (2 \eta - 1)
* & \frac{\partial N3}{\partial \xi} = 0
* & \frac{\partial N3}{\partial \eta} = 4 \eta - 1
* & \frac{\partial N3}{\partial \zeta} = 0 \\
* N4 = \zeta (2 \zeta - 1)
* & \frac{\partial N4}{\partial \xi} = 0
* & \frac{\partial N4}{\partial \eta} = 0
* & \frac{\partial N4}{\partial \zeta} = 4 \zeta - 1 \\
* N5 = 4 \xi (1 - \xi - \eta - \zeta)
* & \frac{\partial N5}{\partial \xi} = 4 - 8 \xi - 4 \eta - 4 \zeta
* & \frac{\partial N5}{\partial \eta} = -4 \xi
* & \frac{\partial N5}{\partial \zeta} = -4 \xi \\
* N6 = 4 \xi \eta
* & \frac{\partial N6}{\partial \xi} = 4 \eta
* & \frac{\partial N6}{\partial \eta} = 4 \xi
* & \frac{\partial N6}{\partial \zeta} = 0 \\
* N7 = 4 \eta (1 - \xi - \eta - \zeta)
* & \frac{\partial N7}{\partial \xi} = -4 \eta
* & \frac{\partial N7}{\partial \eta} = 4 - 4 \xi - 8 \eta - 4 \zeta
* & \frac{\partial N7}{\partial \zeta} = -4 \eta \\
* N8 = 4 \zeta (1 - \xi - \eta - \zeta)
* & \frac{\partial N8}{\partial \xi} = -4 \zeta
* & \frac{\partial N8}{\partial \eta} = -4 \zeta
* & \frac{\partial N8}{\partial \zeta} = 4 - 4 \xi - 4 \eta - 8 \zeta \\
* N9 = 4 \zeta \xi
* & \frac{\partial N9}{\partial \xi} = 4 \zeta
* & \frac{\partial N9}{\partial \eta} = 0
* & \frac{\partial N9}{\partial \zeta} = 4 \xi \\
* N10 = 4 \eta \zeta
* & \frac{\partial N10}{\partial \xi} = 0
* & \frac{\partial N10}{\partial \eta} = 4 \zeta
* & \frac{\partial N10}{\partial \zeta} = 4 \eta \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f[
* a = \frac{5 - \sqrt{5}}{20}\\
* b = \frac{5 + 3 \sqrt{5}}{20}
* \begin{array}{lll}
* \xi_{q_0} = a & \eta_{q_0} = a & \zeta_{q_0} = a \\
* \xi_{q_1} = b & \eta_{q_1} = a & \zeta_{q_1} = a \\
* \xi_{q_2} = a & \eta_{q_2} = b & \zeta_{q_2} = a \\
* \xi_{q_3} = a & \eta_{q_3} = a & \zeta_{q_3} = b
* \end{array}
* @f]
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_tetrahedron_10, _gt_tetrahedron_10, _itp_lagrange_tetrahedron_10, _ek_regular, 3,
_git_tetrahedron, 2);
AKANTU_DEFINE_SHAPE(_gt_tetrahedron_10, _gst_triangle);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_tetrahedron_10>::computeShapes(const vector_type & natural_coords,
vector_type & N) {
/// Natural coordinates
Real xi = natural_coords(0);
Real eta = natural_coords(1);
Real zeta = natural_coords(2);
Real sum = xi + eta + zeta;
Real c0 = 1 - sum;
Real c1 = 1 - 2*sum;
Real c2 = 2*xi - 1;
Real c3 = 2*eta - 1;
Real c4 = 2*zeta - 1;
/// Shape functions
N(0) = c0 * c1;
N(1) = xi * c2;
N(2) = eta * c3;
N(3) = zeta * c4;
N(4) = 4 * xi * c0;
N(5) = 4 * xi * eta;
N(6) = 4 * eta * c0;
N(7) = 4 * zeta * c0;
N(8) = 4 * xi * zeta;
N(9) = 4 * eta * zeta;
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_tetrahedron_10>::computeDNDS(const vector_type & natural_coords,
matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccccccc}
* \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi}
* & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial \xi}
* & \frac{\partial N5}{\partial \xi} & \frac{\partial N6}{\partial \xi}
* & \frac{\partial N7}{\partial \xi} & \frac{\partial N8}{\partial \xi}
* & \frac{\partial N9}{\partial \xi} & \frac{\partial N10}{\partial \xi} \\
* \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta}
* & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial \eta}
* & \frac{\partial N5}{\partial \eta} & \frac{\partial N6}{\partial \eta}
* & \frac{\partial N7}{\partial \eta} & \frac{\partial N8}{\partial \eta}
* & \frac{\partial N9}{\partial \eta} & \frac{\partial N10}{\partial \eta} \\
* \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial \zeta}
* & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial \zeta}
* & \frac{\partial N5}{\partial \zeta} & \frac{\partial N6}{\partial \zeta}
* & \frac{\partial N7}{\partial \zeta} & \frac{\partial N8}{\partial \zeta}
* & \frac{\partial N9}{\partial \zeta} & \frac{\partial N10}{\partial \zeta}
* \end{array}
* \right)
* @f]
*/
/// Natural coordinates
Real xi = natural_coords(0);
Real eta = natural_coords(1);
Real zeta = natural_coords(2);
Real sum = xi + eta + zeta;
/// \frac{\partial N_i}{\partial \xi}
dnds(0, 0) = 4 * sum - 3;
dnds(0, 1) = 4 * xi - 1;
dnds(0, 2) = 0;
dnds(0, 3) = 0;
dnds(0, 4) = 4 * (1 - sum - xi);
dnds(0, 5) = 4 * eta;
dnds(0, 6) = -4 * eta;
dnds(0, 7) = -4 * zeta;
dnds(0, 8) = 4 * zeta;
dnds(0, 9) = 0;
/// \frac{\partial N_i}{\partial \eta}
dnds(1, 0) = 4 * sum - 3;
dnds(1, 1) = 0;
dnds(1, 2) = 4 * eta - 1;
dnds(1, 3) = 0;
dnds(1, 4) = -4 * xi;
dnds(1, 5) = 4 * xi;
dnds(1, 6) = 4 * (1 - sum - eta);
dnds(1, 7) = -4 * zeta;
dnds(1, 8) = 0;
dnds(1, 9) = 4 * zeta;
/// \frac{\partial N_i}{\partial \zeta}
dnds(2, 0) = 4 * sum - 3;
dnds(2, 1) = 0;
dnds(2, 2) = 0;
dnds(2, 3) = 4 * zeta - 1;
dnds(2, 4) = -4 * xi;
dnds(2, 5) = 0;
dnds(2, 6) = -4 * eta;
dnds(2, 7) = 4 * (1 - sum - zeta);
dnds(2, 8) = 4 * xi;
dnds(2, 9) = 4 * eta;
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_tetrahedron_10>::getInradius(const Matrix<Real> & coord) {
// Only take the four corner tetrahedra
UInt tetrahedra[4][4] = {
{0, 4, 6, 7},
{4, 1, 5, 8},
{6, 5, 2, 9},
{7, 8, 9, 3}
};
Real inradius = std::numeric_limits<Real>::max();
for (UInt t = 0; t < 4; t++) {
Real ir = Math::tetrahedron_inradius(coord(tetrahedra[t][0]).storage(),
coord(tetrahedra[t][1]).storage(),
coord(tetrahedra[t][2]).storage(),
coord(tetrahedra[t][3]).storage());
inradius = std::min(ir, inradius);
}
return inradius;
}
diff --git a/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc b/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
index c91a77565..0c4fc13a5 100644
--- a/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
@@ -1,123 +1,124 @@
/**
* @file element_class_tetrahedron_4_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 16 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _tetrahedron_4
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
\eta
^
|
x (0,0,1,0)
|`
| ` ° \xi
| ` ° -
| ` x (0,0,0,1)
| q.` - '
| -` '
| - ` '
| - ` '
x------------------x-----> \zeta
(1,0,0,0) (0,1,0,0)
@endverbatim
*
* @subsection shapes Shape functions
* @f{eqnarray*}{
* N1 &=& 1 - \xi - \eta - \zeta \\
* N2 &=& \xi \\
* N3 &=& \eta \\
* N4 &=& \zeta
* @f}
*
* @subsection quad_points Position of quadrature points
* @f[
* \xi_{q0} = 1/4 \qquad \eta_{q0} = 1/4 \qquad \zeta_{q0} = 1/4
* @f]
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_tetrahedron_4, _gt_tetrahedron_4, _itp_lagrange_tetrahedron_4, _ek_regular, 3,
_git_tetrahedron, 1);
AKANTU_DEFINE_SHAPE(_gt_tetrahedron_4, _gst_triangle);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_tetrahedron_4>::computeShapes(const vector_type & natural_coords,
vector_type & N) {
Real c0 = 1 - natural_coords(0) - natural_coords(1) - natural_coords(2);/// @f$ c2 = 1 - \xi - \eta - \zeta @f$
Real c1 = natural_coords(1); /// @f$ c0 = \xi @f$
Real c2 = natural_coords(2); /// @f$ c1 = \eta @f$
Real c3 = natural_coords(0); /// @f$ c2 = \zeta @f$
N(0) = c0;
N(1) = c1;
N(2) = c2;
N(3) = c3;
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_tetrahedron_4>::computeDNDS(__attribute__ ((unused)) const vector_type & natural_coords,
matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccc}
* \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi}
* & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial \xi} \\
* \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta}
* & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial \eta} \\
* \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial \zeta}
* & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial \zeta}
* \end{array}
* \right)
* @f]
*/
dnds(0, 0) = -1.; dnds(0, 1) = 1.; dnds(0, 2) = 0.; dnds(0, 3) = 0.;
dnds(1, 0) = -1.; dnds(1, 1) = 0.; dnds(1, 2) = 1.; dnds(1, 3) = 0.;
dnds(2, 0) = -1.; dnds(2, 1) = 0.; dnds(2, 2) = 0.; dnds(2, 3) = 1.;
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_tetrahedron_4>::getInradius(const Matrix<Real> & coord) {
return Math::tetrahedron_inradius(coord(0).storage(),
coord(1).storage(),
coord(2).storage(),
coord(3).storage());
}
diff --git a/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc b/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
index 53ab80cdd..bcb991f70 100644
--- a/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
@@ -1,133 +1,134 @@
/**
* @file element_class_triangle_3_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 16 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _triangle_3
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
\eta
^
|
x (0,0,1)
|`
| `
| q `
| ° `
x--------x-----> \xi
(1,0,0) (0,1,0)
@endverbatim
*
* @subsection shapes Shape functions
* @f{eqnarray*}{
* N1 &=& 1 - \xi - \eta \\
* N2 &=& \xi \\
* N3 &=& \eta
* @f}
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 1/3 \qquad \eta_{q0} = 1/3
* @f}
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_triangle_3, _gt_triangle_3, _itp_lagrange_triangle_3, _ek_regular, 2,
_git_triangle, 1);
AKANTU_DEFINE_SHAPE(_gt_triangle_3, _gst_triangle);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_triangle_3>::computeShapes(const vector_type & natural_coords,
vector_type & N) {
/// Natural coordinates
Real c0 = 1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
Real c1 = natural_coords(0); /// @f$ c1 = \xi @f$
Real c2 = natural_coords(1); /// @f$ c2 = \eta @f$
N(0) = c0; /// N1(q_0)
N(1) = c1; /// N2(q_0)
N(2) = c2; /// N3(q_0)
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_triangle_3>::computeDNDS(__attribute__ ((unused)) const vector_type & natural_coords,
matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccc}
* \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi} & \frac{\partial N3}{\partial \xi} \\
* \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta} & \frac{\partial N3}{\partial \eta}
* \end{array}
* \right)
* @f]
*/
dnds(0, 0) = -1.; dnds(0, 1) = 1.; dnds(0, 2) = 0.;
dnds(1, 0) = -1.; dnds(1, 1) = 0.; dnds(1, 2) = 1.;
}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_lagrange_triangle_3>::computeSpecialJacobian(const Matrix<Real> & J,
Real & jac) {
Vector<Real> vprod(J.cols());
Matrix<Real> Jt(J.transpose(), true);
vprod.crossProduct(Jt(0), Jt(1));
jac = vprod.norm();
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_triangle_3>::getInradius(const Matrix<Real> & coord) {
return Math::triangle_inradius(coord(0).storage(),
coord(1).storage(),
coord(2).storage());
}
/* -------------------------------------------------------------------------- */
// template<> inline bool ElementClass<_triangle_3>::contains(const Vector<Real> & natural_coords) {
// if (natural_coords[0] < 0.) return false;
// if (natural_coords[0] > 1.) return false;
// if (natural_coords[1] < 0.) return false;
// if (natural_coords[1] > 1.) return false;
// if (natural_coords[0]+natural_coords[1] > 1.) return false;
// return true;
// }
/* -------------------------------------------------------------------------- */
diff --git a/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc b/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
index 855014af8..4c9885366 100644
--- a/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
@@ -1,205 +1,206 @@
/**
* @file element_class_triangle_6_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 16 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _triangle_6
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @verbatim
\eta
^
|
x 2
| `
| `
| . `
| q2 `
5 x x 4
| `
| `
| .q0 q1. `
| `
x---------x---------x-----> \xi
0 3 1
@endverbatim
*
* @subsection coords Nodes coordinates
*
* @f[
* \begin{array}{ll}
* \xi_{0} = 0 & \eta_{0} = 0 \\
* \xi_{1} = 1 & \eta_{1} = 0 \\
* \xi_{2} = 0 & \eta_{2} = 1 \\
* \xi_{3} = 1/2 & \eta_{3} = 0 \\
* \xi_{4} = 1/2 & \eta_{4} = 1/2 \\
* \xi_{5} = 0 & \eta_{5} = 1/2
* \end{array}
* @f]
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{lll}
* N1 = -(1 - \xi - \eta) (1 - 2 (1 - \xi - \eta))
* & \frac{\partial N1}{\partial \xi} = 1 - 4(1 - \xi - \eta)
* & \frac{\partial N1}{\partial \eta} = 1 - 4(1 - \xi - \eta) \\
* N2 = - \xi (1 - 2 \xi)
* & \frac{\partial N2}{\partial \xi} = - 1 + 4 \xi
* & \frac{\partial N2}{\partial \eta} = 0 \\
* N3 = - \eta (1 - 2 \eta)
* & \frac{\partial N3}{\partial \xi} = 0
* & \frac{\partial N3}{\partial \eta} = - 1 + 4 \eta \\
* N4 = 4 \xi (1 - \xi - \eta)
* & \frac{\partial N4}{\partial \xi} = 4 (1 - 2 \xi - \eta)
* & \frac{\partial N4}{\partial \eta} = - 4 \xi \\
* N5 = 4 \xi \eta
* & \frac{\partial N5}{\partial \xi} = 4 \eta
* & \frac{\partial N5}{\partial \eta} = 4 \xi \\
* N6 = 4 \eta (1 - \xi - \eta)
* & \frac{\partial N6}{\partial \xi} = - 4 \eta
* & \frac{\partial N6}{\partial \eta} = 4 (1 - \xi - 2 \eta)
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 1/6 \qquad \eta_{q0} = 1/6 \\
* \xi_{q1} &=& 2/3 \qquad \eta_{q1} = 1/6 \\
* \xi_{q2} &=& 1/6 \qquad \eta_{q2} = 2/3
* @f}
*/
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_triangle_6, _gt_triangle_6, _itp_lagrange_triangle_6, _ek_regular, 2,
_git_triangle, 2);
AKANTU_DEFINE_SHAPE(_gt_triangle_6, _gst_triangle);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
inline void
InterpolationElement<_itp_lagrange_triangle_6>::computeShapes(const vector_type & natural_coords,
vector_type & N) {
/// Natural coordinates
Real c0 = 1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
Real c1 = natural_coords(0); /// @f$ c1 = \xi @f$
Real c2 = natural_coords(1); /// @f$ c2 = \eta @f$
N(0) = c0 * (2 * c0 - 1.);
N(1) = c1 * (2 * c1 - 1.);
N(2) = c2 * (2 * c2 - 1.);
N(3) = 4 * c0 * c1;
N(4) = 4 * c1 * c2;
N(5) = 4 * c2 * c0;
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
inline void
InterpolationElement<_itp_lagrange_triangle_6>::computeDNDS(const vector_type & natural_coords,
matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccc}
* \frac{\partial N1}{\partial \xi}
* & \frac{\partial N2}{\partial \xi}
* & \frac{\partial N3}{\partial \xi}
* & \frac{\partial N4}{\partial \xi}
* & \frac{\partial N5}{\partial \xi}
* & \frac{\partial N6}{\partial \xi} \\
*
* \frac{\partial N1}{\partial \eta}
* & \frac{\partial N2}{\partial \eta}
* & \frac{\partial N3}{\partial \eta}
* & \frac{\partial N4}{\partial \eta}
* & \frac{\partial N5}{\partial \eta}
* & \frac{\partial N6}{\partial \eta}
* \end{array}
* \right)
* @f]
*/
/// Natural coordinates
Real c0 = 1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
Real c1 = natural_coords(0); /// @f$ c1 = \xi @f$
Real c2 = natural_coords(1); /// @f$ c2 = \eta @f$
dnds(0, 0) = 1 - 4 * c0;
dnds(0, 1) = 4 * c1 - 1.;
dnds(0, 2) = 0.;
dnds(0, 3) = 4 * (c0 - c1);
dnds(0, 4) = 4 * c2;
dnds(0, 5) = - 4 * c2;
dnds(1, 0) = 1 - 4 * c0;
dnds(1, 1) = 0.;
dnds(1, 2) = 4 * c2 - 1.;
dnds(1, 3) = - 4 * c1;
dnds(1, 4) = 4 * c1;
dnds(1, 5) = 4 * (c0 - c2);
}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_lagrange_triangle_6>::computeSpecialJacobian( const Matrix<Real> & J,
Real & jac){
Vector<Real> vprod(J.cols());
Matrix<Real> Jt(J.transpose(), true);
vprod.crossProduct(Jt(0), Jt(1));
jac = vprod.norm();
}
/* -------------------------------------------------------------------------- */
template<>
inline Real
GeometricalElement<_gt_triangle_6>::getInradius(const Matrix<Real> & coord) {
UInt triangles[4][3] = {
{0, 3, 5},
{3, 1, 4},
{3, 4, 5},
{5, 4, 2}
};
Real inradius = std::numeric_limits<Real>::max();
for (UInt t = 0; t < 4; t++) {
Real ir = Math::triangle_inradius(coord(triangles[t][0]).storage(),
coord(triangles[t][1]).storage(),
coord(triangles[t][2]).storage());
inradius = std::min(ir, inradius);
}
return inradius;
}
/* -------------------------------------------------------------------------- */
// template<> inline bool ElementClass<_triangle_6>::contains(const Vector<Real> & natural_coords) {
// return ElementClass<_triangle_3>::contains(natural_coords);
// }
diff --git a/src/fe_engine/fe_engine.cc b/src/fe_engine/fe_engine.cc
index a64268b6f..3ad1b0b2d 100644
--- a/src/fe_engine/fe_engine.cc
+++ b/src/fe_engine/fe_engine.cc
@@ -1,276 +1,277 @@
/**
* @file fe_engine.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Jul 20 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Fri Dec 11 2015
*
* @brief Implementation of the FEEngine class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "fe_engine.hh"
#include "mesh.hh"
#include "element_class.hh"
#include "static_communicator.hh"
#include "aka_math.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
FEEngine::FEEngine(Mesh & mesh, UInt element_dimension, ID id, MemoryID memory_id) :
Memory(id, memory_id), mesh(mesh), normals_on_integration_points("normals_on_quad_points", id) {
AKANTU_DEBUG_IN();
this->element_dimension = (element_dimension != _all_dimensions) ?
element_dimension : mesh.getSpatialDimension();
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FEEngine::init() {
}
/* -------------------------------------------------------------------------- */
FEEngine::~FEEngine() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FEEngine::assembleArray(const Array<Real> & elementary_vect,
Array<Real> & nodal_values,
const Array<Int> & equation_number,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements,
Real scale_factor) const {
AKANTU_DEBUG_IN();
UInt nb_element;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
Array<UInt>::const_iterator< Vector<UInt> > conn_it;
Array<UInt> * filtered_connectivity = NULL;
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
filtered_connectivity = new Array<UInt>(0, nb_nodes_per_element);
FEEngine::filterElementalData(mesh,
mesh.getConnectivity(type, ghost_type),
*filtered_connectivity,
type, ghost_type,
filter_elements);
const Array<UInt> & cfiltered = *filtered_connectivity; // \todo temporary patch
conn_it = cfiltered.begin(nb_nodes_per_element);
} else {
nb_element = mesh.getNbElement(type, ghost_type);
conn_it = mesh.getConnectivity(type, ghost_type).begin(nb_nodes_per_element);
}
AKANTU_DEBUG_ASSERT(elementary_vect.getSize() == nb_element,
"The vector elementary_vect(" << elementary_vect.getID()
<< ") has not the good size.");
AKANTU_DEBUG_ASSERT(elementary_vect.getNbComponent()
== nb_degree_of_freedom*nb_nodes_per_element,
"The vector elementary_vect(" << elementary_vect.getID()
<< ") has not the good number of component."
<< "(" << elementary_vect.getNbComponent()
<< " != " << nb_degree_of_freedom*nb_nodes_per_element << ")");
AKANTU_DEBUG_ASSERT(nodal_values.getNbComponent() == nb_degree_of_freedom,
"The vector nodal_values(" << nodal_values.getID()
<< ") has not the good number of component."
<< "(" << nodal_values.getNbComponent()
<< " != " << nb_degree_of_freedom << ")");
nodal_values.resize(mesh.getNbNodes());
Real * nodal_it = nodal_values.storage();
Array<Real>::const_matrix_iterator elem_it = elementary_vect.begin(nb_degree_of_freedom,
nb_nodes_per_element);
for (UInt el = 0; el < nb_element; ++el, ++elem_it, ++conn_it) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = (*conn_it)(n);
UInt offset_node = node * nb_degree_of_freedom;
const Vector<Real> & elem_data = (*elem_it)(n);
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
nodal_it[equation_number(offset_node + d)]
+= scale_factor * elem_data(d);
}
}
}
delete filtered_connectivity;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FEEngine::assembleMatrix(const Array<Real> & elementary_mat,
SparseMatrix & matrix,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt nb_element;
if(ghost_type == _not_ghost) {
nb_element = mesh.getNbElement(type);
} else {
AKANTU_DEBUG_TO_IMPLEMENT();
}
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
}
AKANTU_DEBUG_ASSERT(elementary_mat.getSize() == nb_element,
"The vector elementary_mat(" << elementary_mat.getID()
<< ") has not the good size.");
AKANTU_DEBUG_ASSERT(elementary_mat.getNbComponent()
== nb_degree_of_freedom * nb_nodes_per_element * nb_degree_of_freedom * nb_nodes_per_element,
"The vector elementary_mat(" << elementary_mat.getID()
<< ") has not the good number of component.");
UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
UInt size = mesh.getNbGlobalNodes() * nb_degree_of_freedom;
Real * elementary_mat_val = elementary_mat.storage();
UInt offset_elementary_mat = elementary_mat.getNbComponent();
Array<Real>::const_matrix_iterator el_mat_it = elementary_mat.begin(size_mat,size_mat);
UInt * connectivity_val = mesh.getConnectivity(type, ghost_type).storage();
Int * eq_nb_val = matrix.getDOFSynchronizer().getGlobalDOFEquationNumbers().storage();
Int * local_eq_nb_val = new Int[size_mat];
for (UInt e = 0; e < nb_element; ++e, ++el_mat_it) {
UInt el = e;
if(filter_elements != empty_filter) el = filter_elements(e);
const Matrix<Real> & el_mat = *el_mat_it;
Int * tmp_local_eq_nb_val = local_eq_nb_val;
UInt * conn_val = connectivity_val + el * nb_nodes_per_element;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
UInt n = conn_val[i];
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
*tmp_local_eq_nb_val++ = eq_nb_val[n * nb_degree_of_freedom + d];
}
// memcpy(tmp_local_eq_nb_val, eq_nb_val + n * nb_degree_of_freedom, nb_degree_of_freedom * sizeof(Int));
// tmp_local_eq_nb_val += nb_degree_of_freedom;
}
/// The matrix assembling for cohesive elements with degenerated nodes
/// (i.e. elements in correspondence of the crack tips) has to be done
/// without considering symmetry
#if defined(AKANTU_COHESIVE_ELEMENT)
if (mesh.getKind(type) == _ek_cohesive){
/// matrix assembling procedure for cohesive elements
for (UInt i = 0; i < size_mat; ++i) {
UInt c_irn = local_eq_nb_val[i];
if(c_irn < size) {
for (UInt j = 0; j < size_mat; ++j) {
UInt c_jcn = local_eq_nb_val[j];
if(c_jcn < size) {
if (matrix.getSparseMatrixType() == _symmetric){
if (c_jcn >= c_irn){
matrix(c_irn, c_jcn) += el_mat(i, j);
}
}else{
matrix(c_irn, c_jcn) += el_mat(i, j);
}
}
}
}
}
elementary_mat_val += offset_elementary_mat;
}else{
#endif
/// matrix assembling procedure for all the elements except cohesive ones
for (UInt i = 0; i < size_mat; ++i) {
UInt c_irn = local_eq_nb_val[i];
if(c_irn < size) {
UInt j_start = (matrix.getSparseMatrixType() == _symmetric) ? i : 0;
for (UInt j = j_start; j < size_mat; ++j) {
UInt c_jcn = local_eq_nb_val[j];
if(c_jcn < size) {
matrix(c_irn, c_jcn) += el_mat(i, j);
}
}
}
}
elementary_mat_val += offset_elementary_mat;
}
#if defined(AKANTU_COHESIVE_ELEMENT)
}
#endif
delete [] local_eq_nb_val;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FEEngine::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "FEEngine [" << std::endl;
stream << space << " + id : " << id << std::endl;
stream << space << " + element dimension : " << element_dimension << std::endl;
stream << space << " + mesh [" << std::endl;
mesh.printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/fe_engine/fe_engine.hh b/src/fe_engine/fe_engine.hh
index aeb6e5c4f..d0014aa02 100644
--- a/src/fe_engine/fe_engine.hh
+++ b/src/fe_engine/fe_engine.hh
@@ -1,403 +1,404 @@
/**
* @file fe_engine.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Jul 20 2010
- * @date last modification: Mon Jul 07 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 22 2015
*
* @brief FEM class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_FE_ENGINE_HH__
#define __AKANTU_FE_ENGINE_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_memory.hh"
#include "mesh.hh"
#include "element_class.hh"
#include "sparse_matrix.hh"
#include "integration_point.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class Integrator;
class ShapeFunctions;
/* -------------------------------------------------------------------------- */
/**
* The generic FEEngine class derived in a FEEngineTemplate class containing the
* shape functions and the integration method
*/
class FEEngine : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
FEEngine(Mesh & mesh, UInt spatial_dimension = _all_dimensions,
ID id = "fem", MemoryID memory_id = 0);
virtual ~FEEngine();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// pre-compute all the shape functions, their derivatives and the jacobians
virtual void initShapeFunctions(const GhostType & ghost_type = _not_ghost) = 0;
/// extract the nodal values and store them per element
template<typename T>
static void extractNodalToElementField(const Mesh & mesh,
const Array<T> & nodal_f,
Array<T> & elemental_f,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter);
/// filter a field
template<typename T>
static void filterElementalData(const Mesh & mesh,
const Array<T> & quad_f,
Array<T> & filtered_f,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter);
/* ------------------------------------------------------------------------ */
/* Integration method bridges */
/* ------------------------------------------------------------------------ */
/// integrate f for all elements of type "type"
virtual void integrate(const Array<Real> & f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const = 0;
/// integrate a scalar value f on all elements of type "type"
virtual Real integrate(const Array<Real> & f,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const = 0;
/// integrate f for all integration points of type "type" but don't sum over all integration points
virtual void integrateOnIntegrationPoints(const Array<Real> & f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const = 0;
/// integrate one element scalar value on all elements of type "type"
virtual Real integrate(const Vector<Real> & f,
const ElementType & type,
UInt index, const GhostType & ghost_type = _not_ghost) const = 0;
/* ------------------------------------------------------------------------ */
/* compatibility with old FEEngine fashion */
/* ------------------------------------------------------------------------ */
#ifndef SWIG
/// get the number of integration points
virtual UInt getNbIntegrationPoints(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const = 0;
/// get the precomputed shapes
const virtual Array<Real> & getShapes(const ElementType & type,
const GhostType & ghost_type = _not_ghost,
UInt id = 0) const = 0;
/// get the derivatives of shapes
const virtual Array<Real> & getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type = _not_ghost,
UInt id = 0) const = 0;
/// get integration points
const virtual Matrix<Real> & getIntegrationPoints(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const = 0;
#endif
/* ------------------------------------------------------------------------ */
/* Shape method bridges */
/* ------------------------------------------------------------------------ */
/// Compute the gradient nablauq on the integration points of an element type from nodal values u
virtual
void gradientOnIntegrationPoints(const Array<Real> &u,
Array<Real> &nablauq,
const UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const = 0;
/// Interpolate a nodal field u at the integration points of an element type -> uq
virtual
void interpolateOnIntegrationPoints(const Array<Real> &u,
Array<Real> &uq,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const = 0;
/// Interpolate a nodal field u at the integration points of many element types -> uq
virtual
void interpolateOnIntegrationPoints(const Array<Real> & u,
ElementTypeMapArray<Real> & uq,
const ElementTypeMapArray<UInt> * filter_elements = NULL) const = 0;
/// Compute the interpolation point position in the global coordinates for many element types
virtual
void computeIntegrationPointsCoordinates(ElementTypeMapArray<Real> & integration_points_coordinates,
const ElementTypeMapArray<UInt> * filter_elements = NULL) const = 0;
/// Compute the interpolation point position in the global coordinates for an element type
virtual
void computeIntegrationPointsCoordinates(Array<Real> & integration_points_coordinates,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const = 0;
/// Build pre-computed matrices for interpolation of field form integration points at other given positions (interpolation_points)
virtual
void initElementalFieldInterpolationFromIntegrationPoints(const ElementTypeMapArray<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
ElementTypeMapArray<Real> & integration_points_coordinates_inv_matrices,
const ElementTypeMapArray<UInt> * element_filter) const = 0;
/// interpolate field at given position (interpolation_points) from given values of this field at integration points (field)
virtual
void interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
const ElementTypeMapArray<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const ElementTypeMapArray<UInt> * element_filter) const = 0;
/// Interpolate field at given position from given values of this field at integration points (field)
/// using matrices precomputed with initElementalFieldInterplationFromIntegrationPoints
virtual
void interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
const ElementTypeMapArray<Real> & integration_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const ElementTypeMapArray<UInt> * element_filter) const = 0;
/// interpolate on a phyiscal point inside an element
virtual
void interpolate(const Vector<Real> & real_coords,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated,
const Element & element) const = 0;
/// compute the shape on a provided point
virtual
void computeShapes(const Vector<Real> & real_coords,
UInt elem,
const ElementType & type,
Vector<Real> & shapes,
const GhostType & ghost_type = _not_ghost) const = 0;
/// compute the shape derivatives on a provided point
virtual
void computeShapeDerivatives(const Vector<Real> & real__coords,
UInt element,
const ElementType & type,
Matrix<Real> & shape_derivatives,
const GhostType & ghost_type = _not_ghost) const = 0;
/* ------------------------------------------------------------------------ */
/* Other methods */
/* ------------------------------------------------------------------------ */
/// pre-compute normals on integration points
virtual void computeNormalsOnIntegrationPoints(const GhostType & ghost_type = _not_ghost) = 0;
/// pre-compute normals on integration points
virtual void computeNormalsOnIntegrationPoints(__attribute__((unused)) const Array<Real> & field,
__attribute__((unused)) const GhostType & ghost_type = _not_ghost) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// pre-compute normals on integration points
virtual void computeNormalsOnIntegrationPoints(__attribute__((unused)) const Array<Real> & field,
__attribute__((unused)) Array<Real> & normal,
__attribute__((unused)) const ElementType & type,
__attribute__((unused)) const GhostType & ghost_type = _not_ghost) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// assemble vectors at nodes from elementary vectors
void assembleArray(const Array<Real> & elementary_vect,
Array<Real> & nodal_values,
const Array<Int> & equation_number,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter,
Real scale_factor = 1) const;
/// assemble matrix in the complete sparse matrix
void assembleMatrix(const Array<Real> & elementary_mat,
SparseMatrix & matrix,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// assemble a field as a lumped matrix (ex. rho in lumped mass)
virtual void assembleFieldLumped(__attribute__ ((unused)) const Array<Real> & field_1,
__attribute__ ((unused)) UInt nb_degree_of_freedom,
__attribute__ ((unused)) Array<Real> & lumped,
__attribute__ ((unused)) const Array<Int> & equation_number,
__attribute__ ((unused)) ElementType type,
__attribute__ ((unused)) const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
};
/// assemble a field as a matrix (ex. rho to mass matrix)
virtual void assembleFieldMatrix(__attribute__ ((unused)) const Array<Real> & field_1,
__attribute__ ((unused)) UInt nb_degree_of_freedom,
__attribute__ ((unused)) SparseMatrix & matrix,
__attribute__ ((unused)) ElementType type,
__attribute__ ((unused)) const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
#ifdef AKANTU_STRUCTURAL_MECHANICS
/// assemble a field as a matrix for structural elements (ex. rho to mass matrix)
virtual void assembleFieldMatrix(__attribute__ ((unused)) const Array<Real> & field_1,
__attribute__ ((unused)) UInt nb_degree_of_freedom,
__attribute__ ((unused)) SparseMatrix & M,
__attribute__ ((unused)) Array<Real> * n,
__attribute__ ((unused)) ElementTypeMapArray<Real> & rotation_mat,
__attribute__ ((unused)) ElementType type,
__attribute__ ((unused)) const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// compute shapes function in a matrix for structural elements
virtual void computeShapesMatrix(__attribute__ ((unused))const ElementType & type,
__attribute__ ((unused))UInt nb_degree_of_freedom,
__attribute__ ((unused))UInt nb_nodes_per_element,
__attribute__ ((unused))Array<Real> * n,
__attribute__ ((unused))UInt id,
__attribute__ ((unused))UInt degree_to_interpolate,
__attribute__ ((unused))UInt degree_interpolated,
__attribute__ ((unused))const bool sign,
__attribute__ ((unused))const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
#endif
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
private:
/// initialise the class
void init();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the dimension of the element handeled by this fe_engine object
AKANTU_GET_MACRO(ElementDimension, element_dimension, UInt);
/// get the mesh contained in the fem object
AKANTU_GET_MACRO(Mesh, mesh, const Mesh &);
/// get the mesh contained in the fem object
AKANTU_GET_MACRO_NOT_CONST(Mesh, mesh, Mesh &);
/// get the in-radius of an element
static inline Real getElementInradius(const Matrix<Real> & coord, const ElementType & type);
/// get the normals on integration points
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NormalsOnIntegrationPoints, normals_on_integration_points, Real);
/// get cohesive element type for a given facet type
static inline ElementType getCohesiveElementType(const ElementType & type_facet);
/// get igfem element type for a given regular type
static inline Vector<ElementType> getIGFEMElementTypes(const ElementType & type);
/// get the interpolation element associated to an element type
static inline InterpolationType getInterpolationType(const ElementType & el_type);
/// get the shape function class (probably useless: see getShapeFunction in fe_engine_template.hh)
virtual const ShapeFunctions & getShapeFunctionsInterface() const = 0;
/// get the integrator class (probably useless: see getIntegrator in fe_engine_template.hh)
virtual const Integrator & getIntegratorInterface() const = 0;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// spatial dimension of the problem
UInt element_dimension;
/// the mesh on which all computation are made
Mesh & mesh;
/// normals at integration points
ElementTypeMapArray<Real> normals_on_integration_points;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const FEEngine & _this)
{
_this.printself(stream);
return stream;
}
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const IntegrationPoint & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#include "fe_engine_inline_impl.cc"
#include "fe_engine_template.hh"
#endif /* __AKANTU_FE_ENGINE_HH__ */
diff --git a/src/fe_engine/fe_engine_inline_impl.cc b/src/fe_engine/fe_engine_inline_impl.cc
index 8d86b1780..0e2bad4fa 100644
--- a/src/fe_engine/fe_engine_inline_impl.cc
+++ b/src/fe_engine/fe_engine_inline_impl.cc
@@ -1,194 +1,195 @@
/**
* @file fe_engine_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Jul 20 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sat Sep 05 2015
*
* @brief Implementation of the inline functions of the FEEngine Class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline Real FEEngine::getElementInradius(const Matrix<Real> & coord, const ElementType & type) {
AKANTU_DEBUG_IN();
Real inradius = 0;
#define GET_INRADIUS(type) \
inradius = ElementClass<type>::getInradius(coord); \
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_INRADIUS);
#undef GET_INRADIUS
AKANTU_DEBUG_OUT();
return inradius;
}
/* -------------------------------------------------------------------------- */
inline InterpolationType FEEngine::getInterpolationType(const ElementType & type) {
AKANTU_DEBUG_IN();
InterpolationType itp_type = _itp_not_defined;
#define GET_ITP(type) \
itp_type = ElementClassProperty<type>::interpolation_type; \
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_ITP);
#undef GET_ITP
AKANTU_DEBUG_OUT();
return itp_type;
}
/* -------------------------------------------------------------------------- */
/// @todo rewrite this function in order to get the cohesive element
/// type directly from the facet
#if defined(AKANTU_COHESIVE_ELEMENT)
inline ElementType FEEngine::getCohesiveElementType(const ElementType & type_facet) {
AKANTU_DEBUG_IN();
ElementType type_cohesive = _not_defined;
if (type_facet == _point_1) type_cohesive = _cohesive_1d_2;
else if (type_facet == _segment_2) type_cohesive = _cohesive_2d_4;
else if (type_facet == _segment_3) type_cohesive = _cohesive_2d_6;
else if (type_facet == _triangle_3) type_cohesive = _cohesive_3d_6;
else if (type_facet == _triangle_6) type_cohesive = _cohesive_3d_12;
else if (type_facet == _quadrangle_4) type_cohesive = _cohesive_3d_8;
else if (type_facet == _quadrangle_8) type_cohesive = _cohesive_3d_16;
AKANTU_DEBUG_OUT();
return type_cohesive;
}
#else
inline ElementType FEEngine::getCohesiveElementType(__attribute__((unused)) const ElementType & type_facet) {
return _not_defined;
}
#endif
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_IGFEM)
__END_AKANTU__
#include "igfem_helper.hh"
__BEGIN_AKANTU__
inline Vector<ElementType> FEEngine::getIGFEMElementTypes(const ElementType & type) {
#define GET_IGFEM_ELEMENT_TYPES(type) \
return IGFEMHelper::getIGFEMElementTypes<type>();
AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(GET_IGFEM_ELEMENT_TYPES);
#undef GET_IGFEM_ELEMENT_TYPES
}
#endif
/* -------------------------------------------------------------------------- */
template<typename T>
void FEEngine::extractNodalToElementField(const Mesh & mesh,
const Array<T> & nodal_f,
Array<T> & elemental_f,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) {
AKANTU_DEBUG_IN();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_degree_of_freedom = nodal_f.getNbComponent();
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
}
elemental_f.resize(nb_element);
T * nodal_f_val = nodal_f.storage();
T * f_val = elemental_f.storage();
UInt * el_conn;
for (UInt el = 0; el < nb_element; ++el) {
if(filter_elements != empty_filter) el_conn = conn_val + filter_elements(el) * nb_nodes_per_element;
else el_conn = conn_val + el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = *(el_conn + n);
std::copy(nodal_f_val + node * nb_degree_of_freedom,
nodal_f_val + (node + 1) * nb_degree_of_freedom,
f_val);
f_val += nb_degree_of_freedom;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T>
void FEEngine::filterElementalData(const Mesh & mesh,
const Array<T> & elem_f,
Array<T> & filtered_f,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) {
AKANTU_DEBUG_IN();
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(nb_element == 0) {
filtered_f.resize(0);
return;
}
UInt nb_degree_of_freedom = elem_f.getNbComponent();
UInt nb_data_per_element = elem_f.getSize() / nb_element;
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
}
filtered_f.resize(nb_element * nb_data_per_element);
T * elem_f_val = elem_f.storage();
T * f_val = filtered_f.storage();
UInt el_offset;
for (UInt el = 0; el < nb_element; ++el) {
if(filter_elements != empty_filter) el_offset = filter_elements(el);
else el_offset = el;
std::copy(elem_f_val + el_offset * nb_data_per_element * nb_degree_of_freedom,
elem_f_val + (el_offset + 1) * nb_data_per_element * nb_degree_of_freedom,
f_val);
f_val += nb_degree_of_freedom * nb_data_per_element;
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/fe_engine/fe_engine_template.hh b/src/fe_engine/fe_engine_template.hh
index 16cec8a11..606a1e9d9 100644
--- a/src/fe_engine/fe_engine_template.hh
+++ b/src/fe_engine/fe_engine_template.hh
@@ -1,365 +1,366 @@
/**
* @file fe_engine_template.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Feb 15 2011
- * @date last modification: Mon Oct 19 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief templated class that calls integration and shape objects
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
#ifndef __AKANTU_FE_ENGINE_TEMPLATE_HH__
#define __AKANTU_FE_ENGINE_TEMPLATE_HH__
/* -------------------------------------------------------------------------- */
#include "fe_engine.hh"
#include "integrator.hh"
#include "shape_functions.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
template<ElementKind k> struct AssembleLumpedTemplateHelper;
template<ElementKind k> struct AssembleFieldMatrixHelper;
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind = _ek_regular>
class FEEngineTemplate : public FEEngine {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef I<kind> Integ;
typedef S<kind> Shape;
FEEngineTemplate(Mesh & mesh, UInt spatial_dimension = _all_dimensions,
ID id = "fem", MemoryID memory_id = 0);
virtual ~FEEngineTemplate();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// pre-compute all the shape functions, their derivatives and the jacobians
void initShapeFunctions(const GhostType & ghost_type = _not_ghost);
void initShapeFunctions(const Array<Real> & nodes,
const GhostType & ghost_type = _not_ghost);
/* ------------------------------------------------------------------------ */
/* Integration method bridges */
/* ------------------------------------------------------------------------ */
/// integrate f for all elements of type "type"
void integrate(const Array<Real> & f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// integrate a scalar value on all elements of type "type"
Real integrate(const Array<Real> & f,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// integrate one element scalar value on all elements of type "type"
virtual Real integrate(const Vector<Real> & f,
const ElementType & type,
UInt index, const GhostType & ghost_type = _not_ghost) const;
/// integrate partially around an integration point (@f$ intf_q = f_q * J_q * w_q @f$)
void integrateOnIntegrationPoints(const Array<Real> & f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// interpolate on a phyiscal point inside an element
void interpolate(const Vector<Real> & real_coords,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated,
const Element & element) const;
/// get the number of integration points
UInt getNbIntegrationPoints(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
/// get shapes precomputed
const Array<Real> & getShapes(const ElementType & type,
const GhostType & ghost_type = _not_ghost,
UInt id=0) const;
/// get the derivatives of shapes
const Array<Real> & getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type = _not_ghost,
UInt id=0) const;
/// get integration points
const inline Matrix<Real> & getIntegrationPoints(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Shape method bridges */
/* ------------------------------------------------------------------------ */
/// compute the gradient of a nodal field on the integration points
void gradientOnIntegrationPoints(const Array<Real> &u,
Array<Real> &nablauq,
const UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// interpolate a nodal field on the integration points
void interpolateOnIntegrationPoints(const Array<Real> &u,
Array<Real> &uq,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// interpolate a nodal field on the integration points given a by_element_type
void interpolateOnIntegrationPoints(const Array<Real> & u,
ElementTypeMapArray<Real> & uq,
const ElementTypeMapArray<UInt> * filter_elements = NULL) const;
/// compute the position of integration points given by an element_type_map from nodes position
inline void computeIntegrationPointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates,
const ElementTypeMapArray<UInt> * filter_elements = NULL) const;
/// compute the position of integration points from nodes position
inline void computeIntegrationPointsCoordinates(Array<Real> & quadrature_points_coordinates,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// interpolate field at given position (interpolation_points) from given values of this field at integration points (field)
inline void interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
const ElementTypeMapArray<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const ElementTypeMapArray<UInt> * element_filter) const;
/// Interpolate field at given position from given values of this field at integration points (field)
/// using matrices precomputed with initElementalFieldInterplationFromIntegrationPoints
inline void interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const ElementTypeMapArray<UInt> * element_filter) const;
/// Build pre-computed matrices for interpolation of field form integration points at other given positions (interpolation_points)
inline void initElementalFieldInterpolationFromIntegrationPoints(const ElementTypeMapArray<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
const ElementTypeMapArray<UInt> * element_filter = NULL) const;
/// find natural coords from real coords provided an element
void inverseMap(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
Vector<Real> & natural_coords,
const GhostType & ghost_type = _not_ghost) const;
/// return true if the coordinates provided are inside the element, false otherwise
inline bool contains(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
/// compute the shape on a provided point
inline void computeShapes(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
Vector<Real> & shapes,
const GhostType & ghost_type = _not_ghost) const;
/// compute the shape derivatives on a provided point
inline void computeShapeDerivatives(const Vector<Real> & real__coords,
UInt element,
const ElementType & type,
Matrix<Real> & shape_derivatives,
const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Other methods */
/* ------------------------------------------------------------------------ */
/// pre-compute normals on integration points
void computeNormalsOnIntegrationPoints(const GhostType & ghost_type = _not_ghost);
void computeNormalsOnIntegrationPoints(const Array<Real> & field,
const GhostType & ghost_type = _not_ghost);
void computeNormalsOnIntegrationPoints(const Array<Real> & field,
Array<Real> & normal,
const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
template<ElementType type>
void computeNormalsOnIntegrationPoints(const Array<Real> & field,
Array<Real> & normal,
const GhostType & ghost_type) const;
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/// assemble a field as a lumped matrix (ex. rho in lumped mass)
void assembleFieldLumped(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
ElementType type,
const GhostType & ghost_type = _not_ghost) const;
/// assemble a field as a matrix (ex. rho to mass matrix)
void assembleFieldMatrix(const Array<Real> & field,
UInt nb_degree_of_freedom,
SparseMatrix & matrix,
ElementType type,
const GhostType & ghost_type = _not_ghost) const;
#ifdef AKANTU_STRUCTURAL_MECHANICS
/// assemble a field as a matrix (ex. rho to mass matrix)
void assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
/// compute shapes function in a matrix for structural elements
void computeShapesMatrix(const ElementType & type,
UInt nb_degree_of_freedom,
UInt nb_nodes_per_element,
Array<Real> * n,
UInt id,
UInt degree_to_interpolate,
UInt degree_interpolated,
const bool sign,
const GhostType & ghost_type = _not_ghost) const;
#endif
private:
friend struct AssembleLumpedTemplateHelper<kind>;
friend struct AssembleFieldMatrixHelper<kind>;
/// templated function to compute the scaling to assemble a lumped matrix
template <ElementType type>
void assembleLumpedTemplate(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const;
/// @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV = \int \rho \varphi_i dV @f$
template <ElementType type>
void assembleLumpedRowSum(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const;
/// @f$ \tilde{M}_{i} = c * M_{ii} = \int_{V_e} \rho dV @f$
template <ElementType type>
void assembleLumpedDiagonalScaling(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const;
/// assemble a field as a matrix (ex. rho to mass matrix)
template <ElementType type>
void assembleFieldMatrix(const Array<Real> & field,
UInt nb_degree_of_freedom,
SparseMatrix & matrix,
const GhostType & ghost_type) const;
#ifdef AKANTU_STRUCTURAL_MECHANICS
/// assemble a field as a matrix for structural elements (ex. rho to mass matrix)
template <ElementType type>
void assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const GhostType & ghost_type) const;
#endif
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the shape class (probably useless: see getShapeFunction)
const ShapeFunctions & getShapeFunctionsInterface() const { return shape_functions; };
/// get the shape class
const Shape & getShapeFunctions() const { return shape_functions; };
/// get the integrator class (probably useless: see getIntegrator)
const Integrator & getIntegratorInterface() const { return integrator; };
/// get the integrator class
const Integ & getIntegrator() const { return integrator; };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
Integ integrator;
Shape shape_functions;
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "fe_engine_template_tmpl.hh"
/* -------------------------------------------------------------------------- */
/* Shape Linked specialization */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_STRUCTURAL_MECHANICS)
# include "fe_engine_template_tmpl_struct.hh"
#endif
/* -------------------------------------------------------------------------- */
/* Shape IGFEM specialization */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_IGFEM)
# include "fe_engine_template_tmpl_igfem.hh"
#endif
#endif /* __AKANTU_FE_ENGINE_TEMPLATE_HH__ */
diff --git a/src/fe_engine/fe_engine_template_cohesive.cc b/src/fe_engine/fe_engine_template_cohesive.cc
index 17515c487..53f7efa88 100644
--- a/src/fe_engine/fe_engine_template_cohesive.cc
+++ b/src/fe_engine/fe_engine_template_cohesive.cc
@@ -1,173 +1,174 @@
/**
* @file fe_engine_template_cohesive.cc
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Oct 31 2012
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Specialization of the FEEngineTemplate for cohesive element
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "fe_engine_template.hh"
#include "shape_cohesive.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* compatibility functions */
/* -------------------------------------------------------------------------- */
template <>
Real FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>::integrate(const Array<Real> & f,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const{
AKANTU_DEBUG_IN();
#ifndef AKANTU_NDEBUG
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements != empty_filter) nb_element = filter_elements.getSize();
UInt nb_quadrature_points = getNbIntegrationPoints(type);
AKANTU_DEBUG_ASSERT(f.getSize() == nb_element * nb_quadrature_points,
"The vector f(" << f.getID()
<< ") has not the good size.");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == 1,
"The vector f(" << f.getID()
<< ") has not the good number of component.");
#endif
Real integral = 0.;
#define INTEGRATE(type) \
integral = integrator. integrate<type>(f, \
ghost_type, \
filter_elements);
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INTEGRATE);
#undef INTEGRATE
AKANTU_DEBUG_OUT();
return integral;
}
/* -------------------------------------------------------------------------- */
template <>
void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>
::integrate(const Array<Real> & f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const{
#ifndef AKANTU_NDEBUG
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements == filter_elements) nb_element = filter_elements.getSize();
UInt nb_quadrature_points = getNbIntegrationPoints(type);
AKANTU_DEBUG_ASSERT(f.getSize() == nb_element * nb_quadrature_points,
"The vector f(" << f.getID() << " size " << f.getSize()
<< ") has not the good size (" << nb_element << ").");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom ,
"The vector f(" << f.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
"The vector intf(" << intf.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(intf.getSize() == nb_element,
"The vector intf(" << intf.getID()
<< ") has not the good size.");
#endif
#define INTEGRATE(type) \
integrator. integrate<type>(f, \
intf, \
nb_degree_of_freedom, \
ghost_type, \
filter_elements);
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INTEGRATE);
#undef INTEGRATE
}
/* -------------------------------------------------------------------------- */
template <>
void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>::
gradientOnIntegrationPoints(__attribute__((unused)) const Array<Real> &u,
__attribute__((unused)) Array<Real> &nablauq,
__attribute__((unused)) const UInt nb_degree_of_freedom,
__attribute__((unused)) const ElementType & type,
__attribute__((unused)) const GhostType & ghost_type,
__attribute__((unused)) const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template<>
template<>
void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>::
computeNormalsOnIntegrationPoints<_cohesive_1d_2>(__attribute__((unused)) const Array<Real> & field,
Array<Real> & normal,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == 1, "Mesh dimension must be 1 to compute normals on 1D cohesive elements!");
const ElementType type = _cohesive_1d_2;
const ElementType facet_type = Mesh::getFacetType(type);
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
normal.resize(nb_element);
Array<Element> & facets =
mesh.getMeshFacets().getSubelementToElement(type, ghost_type);
Array<std::vector<Element> > & segments =
mesh.getMeshFacets().getElementToSubelement(facet_type, ghost_type);
Real values[2];
for (UInt elem = 0; elem < nb_element; ++elem) {
for (UInt p = 0; p < 2; ++p) {
Element f = facets(elem, p);
Element seg = segments(f.element)[0];
mesh.getBarycenter(seg.element, seg.type, &(values[p]), seg.ghost_type);
}
Real difference = values[0] - values[1];
AKANTU_DEBUG_ASSERT(difference != 0.,
"Error in normal computation for cohesive elements");
normal(elem) = difference / std::abs(difference);
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/fe_engine/fe_engine_template_tmpl.hh b/src/fe_engine/fe_engine_template_tmpl.hh
index c923e9c34..a053ec008 100644
--- a/src/fe_engine/fe_engine_template_tmpl.hh
+++ b/src/fe_engine/fe_engine_template_tmpl.hh
@@ -1,1726 +1,1729 @@
/**
* @file fe_engine_template_tmpl.hh
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Mon Nov 05 2012
- * @date last modification: Mon Jul 07 2014
+ * @date creation: Tue Feb 15 2011
+ * @date last modification: Thu Nov 19 2015
*
* @brief Template implementation of FEEngineTemplate
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
FEEngineTemplate<I, S, kind>::FEEngineTemplate(Mesh & mesh, UInt spatial_dimension,
ID id, MemoryID memory_id) :
FEEngine(mesh,spatial_dimension,id,memory_id),
integrator(mesh, id, memory_id),
shape_functions(mesh, id, memory_id) { }
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
FEEngineTemplate<I, S, kind>::~FEEngineTemplate() { }
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct GradientOnIntegrationPointsHelper {
template <class S>
static void call(const S & shape_functions,
Mesh & mesh,
const Array<Real> & u,
Array<Real> & nablauq,
const UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define COMPUTE_GRADIENT(type) \
if (element_dimension == ElementClass<type>::getSpatialDimension()) \
shape_functions.template gradientOnIntegrationPoints<type>(u, \
nablauq, \
nb_degree_of_freedom, \
ghost_type, \
filter_elements);
#define AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER(kind) \
template<> \
struct GradientOnIntegrationPointsHelper<kind> { \
template <class S> \
static void call(const S & shape_functions, \
Mesh & mesh, \
const Array<Real> & u, \
Array<Real> & nablauq, \
const UInt nb_degree_of_freedom, \
const ElementType & type, \
const GhostType & ghost_type, \
const Array<UInt> & filter_elements) { \
UInt element_dimension = mesh.getSpatialDimension(type); \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_GRADIENT, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER, \
AKANTU_FE_ENGINE_LIST_GRADIENT_ON_INTEGRATION_POINTS)
#undef AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER
#undef COMPUTE_GRADIENT
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::gradientOnIntegrationPoints(const Array<Real> &u,
Array<Real> &nablauq,
const UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements != empty_filter) nb_element = filter_elements.getSize();
UInt nb_points = shape_functions.getIntegrationPoints(type, ghost_type).cols();
#ifndef AKANTU_NDEBUG
UInt element_dimension = mesh.getSpatialDimension(type);
AKANTU_DEBUG_ASSERT(u.getSize() == mesh.getNbNodes(),
"The vector u(" << u.getID()
<< ") has not the good size.");
AKANTU_DEBUG_ASSERT(u.getNbComponent() == nb_degree_of_freedom ,
"The vector u(" << u.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(nablauq.getNbComponent()
== nb_degree_of_freedom * element_dimension,
"The vector nablauq(" << nablauq.getID()
<< ") has not the good number of component.");
// AKANTU_DEBUG_ASSERT(nablauq.getSize() == nb_element * nb_points,
// "The vector nablauq(" << nablauq.getID()
// << ") has not the good size.");
#endif
nablauq.resize(nb_element * nb_points);
GradientOnIntegrationPointsHelper<kind>::call(shape_functions,
mesh,
u,
nablauq,
nb_degree_of_freedom,
type,
ghost_type,
filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::initShapeFunctions(const GhostType & ghost_type) {
initShapeFunctions(mesh.getNodes(), ghost_type);
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::initShapeFunctions(const Array<Real> & nodes,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = mesh.firstType(element_dimension, ghost_type, kind);
Mesh::type_iterator end = mesh.lastType(element_dimension, ghost_type, kind);
for(; it != end; ++it) {
ElementType type = *it;
integrator.initIntegrator(nodes, type, ghost_type);
const Matrix<Real> & control_points =
getIntegrationPoints(type, ghost_type);
shape_functions.initShapeFunctions(nodes, control_points, type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct IntegrateHelper { };
#define INTEGRATE(type) \
integrator.template integrate<type>(f, \
intf, \
nb_degree_of_freedom, \
ghost_type, \
filter_elements); \
#define AKANTU_SPECIALIZE_INTEGRATE_HELPER(kind) \
template<> \
struct IntegrateHelper<kind> { \
template <class I> \
static void call(const I & integrator, \
const Array<Real> & f, \
Array<Real> &intf, \
UInt nb_degree_of_freedom, \
const ElementType & type, \
const GhostType & ghost_type, \
const Array<UInt> & filter_elements) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind); \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_HELPER)
#undef AKANTU_SPECIALIZE_INTEGRATE_HELPER
#undef INTEGRATE
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::integrate(const Array<Real> & f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const{
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements != empty_filter) nb_element = filter_elements.getSize();
#ifndef AKANTU_NDEBUG
UInt nb_quadrature_points = getNbIntegrationPoints(type);
AKANTU_DEBUG_ASSERT(f.getSize() == nb_element * nb_quadrature_points,
"The vector f(" << f.getID() << " size " << f.getSize()
<< ") has not the good size (" << nb_element << ").");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom ,
"The vector f(" << f.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
"The vector intf(" << intf.getID()
<< ") has not the good number of component.");
#endif
intf.resize(nb_element);
IntegrateHelper<kind>::call(integrator,
f,
intf,
nb_degree_of_freedom,
type,
ghost_type,
filter_elements);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct IntegrateScalarHelper { };
#define INTEGRATE(type) \
integral = integrator.template integrate<type>(f, \
ghost_type, filter_elements);
#define AKANTU_SPECIALIZE_INTEGRATE_SCALAR_HELPER(kind) \
template<> \
struct IntegrateScalarHelper<kind> { \
template <class I> \
static Real call(const I & integrator, \
const Array<Real> & f, \
const ElementType & type, \
const GhostType & ghost_type, \
const Array<UInt> & filter_elements) { \
Real integral = 0.; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind); \
return integral; \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_SCALAR_HELPER)
#undef AKANTU_SPECIALIZE_INTEGRATE_SCALAR_HELPER
#undef INTEGRATE
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
Real FEEngineTemplate<I, S, kind>::integrate(const Array<Real> & f,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const{
AKANTU_DEBUG_IN();
#ifndef AKANTU_NDEBUG
// std::stringstream sstr; sstr << ghost_type;
// AKANTU_DEBUG_ASSERT(sstr.str() == nablauq.getTag(),
// "The vector " << nablauq.getID() << " is not taged " << ghost_type);
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements != empty_filter) nb_element = filter_elements.getSize();
UInt nb_quadrature_points = getNbIntegrationPoints(type, ghost_type);
AKANTU_DEBUG_ASSERT(f.getSize() == nb_element * nb_quadrature_points,
"The vector f(" << f.getID()
<< ") has not the good size. (" << f.getSize() << "!=" << nb_quadrature_points * nb_element << ")");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == 1,
"The vector f(" << f.getID()
<< ") has not the good number of component.");
#endif
Real integral = IntegrateScalarHelper<kind>::call(integrator, f, type, ghost_type, filter_elements);
AKANTU_DEBUG_OUT();
return integral;
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct IntegrateScalarOnOneElementHelper { };
#define INTEGRATE(type) \
res = integrator.template integrate<type>(f, \
index, ghost_type);
#define AKANTU_SPECIALIZE_INTEGRATE_SCALAR_ON_ONE_ELEMENT_HELPER(kind) \
template<> \
struct IntegrateScalarOnOneElementHelper<kind> { \
template <class I> \
static Real call(const I & integrator, \
const Vector<Real> & f, \
const ElementType & type, \
UInt index, \
const GhostType & ghost_type) { \
Real res = 0.; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind); \
return res; \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_SCALAR_ON_ONE_ELEMENT_HELPER)
#undef AKANTU_SPECIALIZE_INTEGRATE_SCALAR_ON_ONE_ELEMENT_HELPER
#undef INTEGRATE
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
Real FEEngineTemplate<I, S, kind>::integrate(const Vector<Real> & f,
const ElementType & type,
UInt index,
const GhostType & ghost_type) const{
Real res = IntegrateScalarOnOneElementHelper<kind>::call(integrator, f, type, index, ghost_type);
return res;
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct IntegrateOnIntegrationPointsHelper { };
#define INTEGRATE(type) \
integrator.template integrateOnQuadraturePoints<type>(f, intf, nb_degree_of_freedom, \
ghost_type, filter_elements);
#define AKANTU_SPECIALIZE_INTEGRATE_ON_INTEGRATION_POINTS_HELPER(kind) \
template<> \
struct IntegrateOnIntegrationPointsHelper<kind> { \
template <class I> \
static void call(const I & integrator, \
const Array<Real> & f, \
Array<Real> & intf, \
UInt nb_degree_of_freedom, \
const ElementType & type, \
const GhostType & ghost_type, \
const Array<UInt> & filter_elements) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind); \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_ON_INTEGRATION_POINTS_HELPER)
#undef AKANTU_SPECIALIZE_INTEGRATE_ON_INTEGRATION_POINTS_HELPER
#undef INTEGRATE
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::integrateOnIntegrationPoints(const Array<Real> & f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const{
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements != empty_filter) nb_element = filter_elements.getSize();
UInt nb_quadrature_points = getNbIntegrationPoints(type);
#ifndef AKANTU_NDEBUG
// std::stringstream sstr; sstr << ghost_type;
// AKANTU_DEBUG_ASSERT(sstr.str() == nablauq.getTag(),
// "The vector " << nablauq.getID() << " is not taged " << ghost_type);
AKANTU_DEBUG_ASSERT(f.getSize() == nb_element * nb_quadrature_points,
"The vector f(" << f.getID() << " size " << f.getSize()
<< ") has not the good size (" << nb_element << ").");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom ,
"The vector f(" << f.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
"The vector intf(" << intf.getID()
<< ") has not the good number of component.");
#endif
intf.resize(nb_element*nb_quadrature_points);
IntegrateOnIntegrationPointsHelper<kind>::call(integrator, f, intf, nb_degree_of_freedom, type, ghost_type, filter_elements);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct InterpolateOnIntegrationPointsHelper {
template <class S>
static void call(const S & shape_functions,
const Array<Real> &u,
Array<Real> &uq,
const UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define INTERPOLATE(type) \
shape_functions.template interpolateOnIntegrationPoints<type>(u, \
uq, \
nb_degree_of_freedom, \
ghost_type, \
filter_elements);
#define AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER(kind) \
template<> \
struct InterpolateOnIntegrationPointsHelper<kind> { \
template <class S> \
static void call(const S & shape_functions, \
const Array<Real> & u, \
Array<Real> & uq, \
const UInt nb_degree_of_freedom, \
const ElementType & type, \
const GhostType & ghost_type, \
const Array<UInt> & filter_elements) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTERPOLATE, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER, \
AKANTU_FE_ENGINE_LIST_INTERPOLATE_ON_INTEGRATION_POINTS)
#undef AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER
#undef INTERPOLATE
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::interpolateOnIntegrationPoints(const Array<Real> &u,
Array<Real> &uq,
const UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt nb_points = shape_functions.getIntegrationPoints(type, ghost_type).cols();
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements != empty_filter) nb_element = filter_elements.getSize();
#ifndef AKANTU_NDEBUG
AKANTU_DEBUG_ASSERT(u.getSize() == mesh.getNbNodes(),
"The vector u(" << u.getID()
<< ") has not the good size.");
AKANTU_DEBUG_ASSERT(u.getNbComponent() == nb_degree_of_freedom ,
"The vector u(" << u.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(uq.getNbComponent() == nb_degree_of_freedom,
"The vector uq(" << uq.getID()
<< ") has not the good number of component.");
#endif
uq.resize(nb_element * nb_points);
InterpolateOnIntegrationPointsHelper<kind>::call(shape_functions,
u,
uq,
nb_degree_of_freedom,
type,
ghost_type,
filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::interpolateOnIntegrationPoints(const Array<Real> & u,
ElementTypeMapArray<Real> & uq,
const ElementTypeMapArray<UInt> * filter_elements) const {
AKANTU_DEBUG_IN();
const Array<UInt> * filter = NULL;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
ElementTypeMapArray<Real>::type_iterator it = uq.firstType(_all_dimensions, ghost_type, kind);
ElementTypeMapArray<Real>::type_iterator last = uq.lastType(_all_dimensions, ghost_type, kind);
for (; it != last; ++it) {
ElementType type = *it;
UInt nb_quad_per_element = getNbIntegrationPoints(type, ghost_type);
UInt nb_element = 0;
if (filter_elements) {
filter = &((*filter_elements)(type, ghost_type));
nb_element = filter->getSize();
}
else {
filter = &empty_filter;
nb_element = mesh.getNbElement(type, ghost_type);
}
UInt nb_tot_quad = nb_quad_per_element * nb_element;
Array<Real> & quad = uq(type, ghost_type);
quad.resize(nb_tot_quad);
interpolateOnIntegrationPoints(u,
quad,
quad.getNbComponent(),
type,
ghost_type,
*filter);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::computeIntegrationPointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates,
const ElementTypeMapArray<UInt> * filter_elements) const {
const Array<Real> & nodes_coordinates = mesh.getNodes();
interpolateOnIntegrationPoints(nodes_coordinates, quadrature_points_coordinates, filter_elements);
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::computeIntegrationPointsCoordinates(Array<Real> & quadrature_points_coordinates,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
const Array<Real> & nodes_coordinates = mesh.getNodes();
UInt spatial_dimension = mesh.getSpatialDimension();
interpolateOnIntegrationPoints(nodes_coordinates, quadrature_points_coordinates, spatial_dimension,
type, ghost_type, filter_elements);
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::initElementalFieldInterpolationFromIntegrationPoints(const ElementTypeMapArray<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
const ElementTypeMapArray<UInt> * element_filter) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = this->mesh.getSpatialDimension();
ElementTypeMapArray<Real> quadrature_points_coordinates("quadrature_points_coordinates_for_interpolation", getID());
mesh.initElementTypeMapArray(quadrature_points_coordinates, spatial_dimension, spatial_dimension);
computeIntegrationPointsCoordinates(quadrature_points_coordinates, element_filter);
shape_functions.initElementalFieldInterpolationFromIntegrationPoints(interpolation_points_coordinates,
interpolation_points_coordinates_matrices,
quad_points_coordinates_inv_matrices,
quadrature_points_coordinates,
element_filter);
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
const ElementTypeMapArray<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const ElementTypeMapArray<UInt> * element_filter) const {
ElementTypeMapArray<Real> interpolation_points_coordinates_matrices("interpolation_points_coordinates_matrices");
ElementTypeMapArray<Real> quad_points_coordinates_inv_matrices("quad_points_coordinates_inv_matrices");
initElementalFieldInterpolationFromIntegrationPoints(interpolation_points_coordinates,
interpolation_points_coordinates_matrices,
quad_points_coordinates_inv_matrices,
element_filter);
interpolateElementalFieldFromIntegrationPoints(field,
interpolation_points_coordinates_matrices,
quad_points_coordinates_inv_matrices,
result,
ghost_type,
element_filter);
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const ElementTypeMapArray<UInt> * element_filter) const {
shape_functions.interpolateElementalFieldFromIntegrationPoints(field,
interpolation_points_coordinates_matrices,
quad_points_coordinates_inv_matrices,
result,
ghost_type,
element_filter);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct InterpolateHelper {
template <class S>
static void call(const S & shape_functions,
const Vector<Real> & real_coords,
UInt elem,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define INTERPOLATE(type) \
shape_functions.template interpolate<type>(real_coords, \
element, \
nodal_values, \
interpolated, \
ghost_type);
#define AKANTU_SPECIALIZE_INTERPOLATE_HELPER(kind) \
template<> \
struct InterpolateHelper<kind> { \
template <class S> \
static void call(const S & shape_functions, \
const Vector<Real> & real_coords, \
UInt element, \
const Matrix<Real> & nodal_values, \
Vector<Real> & interpolated, \
const ElementType & type, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTERPOLATE, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INTERPOLATE_HELPER, \
AKANTU_FE_ENGINE_LIST_INTERPOLATE)
#undef AKANTU_SPECIALIZE_INTERPOLATE_HELPER
#undef INTERPOLATE
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::interpolate(const Vector<Real> & real_coords,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated,
const Element & element) const{
AKANTU_DEBUG_IN();
InterpolateHelper<kind>::call(shape_functions, real_coords, element.element, nodal_values, interpolated, element.type, element.ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
computeNormalsOnIntegrationPoints(mesh.getNodes(),
ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(const Array<Real> & field,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
// Real * coord = mesh.getNodes().storage();
UInt spatial_dimension = mesh.getSpatialDimension();
//allocate the normal arrays
Mesh::type_iterator it = mesh.firstType(element_dimension, ghost_type, kind);
Mesh::type_iterator end = mesh.lastType(element_dimension, ghost_type, kind);
for(; it != end; ++it) {
ElementType type = *it;
UInt size = mesh.getNbElement(type, ghost_type);
if(normals_on_integration_points.exists(type, ghost_type)) {
normals_on_integration_points(type, ghost_type).resize(size);
} else {
normals_on_integration_points.alloc(size, spatial_dimension, type, ghost_type);
}
}
//loop over the type to build the normals
it = mesh.firstType(element_dimension, ghost_type, kind);
for(; it != end; ++it) {
Array<Real> & normals_on_quad = normals_on_integration_points(*it, ghost_type);
computeNormalsOnIntegrationPoints(field, normals_on_quad, *it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct ComputeNormalsOnIntegrationPoints {
template <template <ElementKind> class I,
template <ElementKind> class S,
ElementKind k>
static void call(const FEEngineTemplate<I, S, k> & fem,
const Array<Real> & field,
Array<Real> & normal,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define COMPUTE_NORMALS_ON_INTEGRATION_POINTS(type) \
fem.template computeNormalsOnIntegrationPoints<type>(field, normal, ghost_type);
#define AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS(kind) \
template<> \
struct ComputeNormalsOnIntegrationPoints<kind> { \
template <template <ElementKind> class I, \
template <ElementKind> class S, \
ElementKind k> \
static void call(const FEEngineTemplate<I, S, k> & fem, \
const Array<Real> & field, \
Array<Real> & normal, \
const ElementType & type, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_NORMALS_ON_INTEGRATION_POINTS, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS, \
AKANTU_FE_ENGINE_LIST_COMPUTE_NORMALS_ON_INTEGRATION_POINTS)
#undef AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS
#undef COMPUTE_NORMALS_ON_INTEGRATION_POINTS
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(const Array<Real> & field,
Array<Real> & normal,
const ElementType & type,
const GhostType & ghost_type) const {
ComputeNormalsOnIntegrationPoints<kind>::call(*this,
field,
normal,
type,
ghost_type);
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
template<ElementType type>
void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(const Array<Real> & field,
Array<Real> & normal,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_points = getNbIntegrationPoints(type, ghost_type);
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
normal.resize(nb_element * nb_points);
Array<Real>::matrix_iterator normals_on_quad = normal.begin_reinterpret(spatial_dimension,
nb_points,
nb_element);
Array<Real> f_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, field, f_el, type, ghost_type);
const Matrix<Real> & quads =
integrator. template getQuadraturePoints<type>(ghost_type);
Array<Real>::matrix_iterator f_it = f_el.begin(spatial_dimension, nb_nodes_per_element);
for (UInt elem = 0; elem < nb_element; ++elem) {
ElementClass<type>::computeNormalsOnNaturalCoordinates(quads,
*f_it,
*normals_on_quad);
++normals_on_quad;
++f_it;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* Matrix lumping functions */
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct AssembleLumpedTemplateHelper { };
#define ASSEMBLE_LUMPED(type) \
fem.template assembleLumpedTemplate<type>(field_1, nb_degree_of_freedom,lumped, equation_number,ghost_type)
#define AKANTU_SPECIALIZE_ASSEMBLE_HELPER(kind) \
template<> \
struct AssembleLumpedTemplateHelper<kind> { \
template <template <ElementKind> class I, \
template <ElementKind> class S, \
ElementKind k> \
static void call(const FEEngineTemplate<I, S, k> & fem, \
const Array<Real> & field_1, \
UInt nb_degree_of_freedom, \
Array<Real> & lumped, \
const Array<Int> & equation_number, \
ElementType type, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_LUMPED, kind); \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_ASSEMBLE_HELPER)
#undef AKANTU_SPECIALIZE_ASSEMBLE_HELPER
#undef ASSEMBLE_LUMPED
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::assembleFieldLumped(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
ElementType type,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AssembleLumpedTemplateHelper<kind>::call(*this, field_1,
nb_degree_of_freedom,
lumped,
equation_number,
type,
ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct AssembleFieldMatrixHelper { };
#define ASSEMBLE_MATRIX(type) \
fem.template assembleFieldMatrix<type>(field_1, nb_degree_of_freedom, \
matrix, \
ghost_type)
#define AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER(kind) \
template<> \
struct AssembleFieldMatrixHelper<kind> { \
template <template <ElementKind> class I, \
template <ElementKind> class S, \
ElementKind k> \
static void call(const FEEngineTemplate<I, S, k> & fem, \
const Array<Real> & field_1, \
UInt nb_degree_of_freedom, \
SparseMatrix & matrix, \
ElementType type, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_MATRIX, kind); \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER)
#undef AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER
#undef ASSEMBLE_MATRIX
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & matrix,
ElementType type,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AssembleFieldMatrixHelper<kind>::call(*this, field_1, nb_degree_of_freedom, matrix, type, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleLumpedTemplate(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const {
this->template assembleLumpedRowSum<type>(field_1, nb_degree_of_freedom,lumped, equation_number,ghost_type);
}
/* -------------------------------------------------------------------------- */
/**
* @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV = \int \rho \varphi_i dV @f$
*/
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleLumpedRowSum(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt shapes_size = ElementClass<type>::getShapeSize();
Array<Real> * field_times_shapes = new Array<Real>(0, shapes_size * nb_degree_of_freedom);
Array<Real> * field = new Array<Real>(field_1.getSize(), nb_degree_of_freedom);
Array<Real>::const_scalar_iterator f1_it = field_1.begin();
Array<Real>::const_scalar_iterator f1_end = field_1.end();
Array<Real>::vector_iterator f_it = field->begin(nb_degree_of_freedom);
for(;f1_it != f1_end; ++f1_it, ++f_it) {
f_it->set(*f1_it);
}
shape_functions.template fieldTimesShapes<type>(*field, *field_times_shapes, ghost_type);
delete field;
UInt nb_element = mesh.getNbElement(type, ghost_type);
Array<Real> * int_field_times_shapes = new Array<Real>(nb_element, shapes_size * nb_degree_of_freedom,
"inte_rho_x_shapes");
integrator.template integrate<type>(*field_times_shapes, *int_field_times_shapes,
nb_degree_of_freedom * shapes_size, ghost_type, empty_filter);
delete field_times_shapes;
assembleArray(*int_field_times_shapes, lumped, equation_number,nb_degree_of_freedom, type, ghost_type);
delete int_field_times_shapes;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* @f$ \tilde{M}_{i} = c * M_{ii} = \int_{V_e} \rho dV @f$
*/
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleLumpedDiagonalScaling(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
const ElementType & type_p1 = ElementClass<type>::getP1ElementType();
UInt nb_nodes_per_element_p1 = Mesh::getNbNodesPerElement(type_p1);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = integrator.template getQuadraturePoints<type>(ghost_type).cols();
UInt nb_element = field_1.getSize() / nb_quadrature_points;
Vector<Real> nodal_factor(nb_nodes_per_element);
#define ASSIGN_WEIGHT_TO_NODES(corner,mid) \
{ \
for (UInt n = 0; n < nb_nodes_per_element_p1; n++) \
nodal_factor(n) = corner; \
for (UInt n = nb_nodes_per_element_p1; \
n < nb_nodes_per_element; n++) \
nodal_factor(n) = mid; \
}
if (type == _triangle_6 ) ASSIGN_WEIGHT_TO_NODES(1./12., 1./4.);
if (type == _tetrahedron_10) ASSIGN_WEIGHT_TO_NODES(1./32., 7./48.);
if (type == _quadrangle_8 ) ASSIGN_WEIGHT_TO_NODES(3./76., 16./76.); /** coeff. derived by scaling the diagonal terms of the corresponding
* consistent mass computed with 3x3 gauss points;
* coeff. are (1./36., 8./36.) for 2x2 gauss points */
if (type == _hexahedron_20 ) ASSIGN_WEIGHT_TO_NODES(7./248., 16./248.); /** coeff. derived by scaling the diagonal terms of the corresponding
* consistent mass computed with 3x3x3 gauss points;
* coeff. are (1./40., 1./15.) for 2x2x2 gauss points */
if (type == _pentahedron_15) {
// coefficients derived by scaling the diagonal terms of the corresponding consistent mass computed with 8 gauss points;
for (UInt n = 0; n < nb_nodes_per_element_p1; n++)
nodal_factor(n) = 51./2358.;
Real mid_triangle = 192./2358.;
Real mid_quadrangle = 300./2358.;
nodal_factor(6) = mid_triangle;
nodal_factor(7) = mid_triangle;
nodal_factor(8) = mid_triangle;
nodal_factor(9) = mid_quadrangle;
nodal_factor(10) = mid_quadrangle;
nodal_factor(11) = mid_quadrangle;
nodal_factor(12) = mid_triangle;
nodal_factor(13) = mid_triangle;
nodal_factor(14) = mid_triangle;
}
if (nb_element == 0) {
AKANTU_DEBUG_OUT();
return;
}
#undef ASSIGN_WEIGHT_TO_NODES
/// compute @f$ \int \rho dV = \rho V @f$ for each element
Array<Real> * int_field_1 = new Array<Real>(field_1.getSize(), 1,
"inte_rho_x_1");
integrator.template integrate<type>(field_1, *int_field_1, 1, ghost_type, empty_filter);
/// distribute the mass of the element to the nodes
Array<Real> * lumped_per_node = new Array<Real>(nb_element, nb_degree_of_freedom * nb_nodes_per_element, "mass_per_node");
Array<Real>::const_scalar_iterator int_field_1_it = int_field_1->begin();
Array<Real>::matrix_iterator lumped_per_node_it
= lumped_per_node->begin(nb_degree_of_freedom, nb_nodes_per_element);
for (UInt e = 0; e < nb_element; ++e) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
Real lmass = *int_field_1_it * nodal_factor(n);
Vector<Real> l = (*lumped_per_node_it)(n);
l.set(lmass);
}
++int_field_1_it;
++lumped_per_node_it;
}
delete int_field_1;
// lumped_per_node->extendComponentsInterlaced(nb_degree_of_freedom,1);
assembleArray(*lumped_per_node, lumped, equation_number, nb_degree_of_freedom, type, ghost_type);
delete lumped_per_node;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV = \int \rho \varphi_i dV @f$
*/
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & matrix,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt vect_size = field_1.getSize();
UInt shapes_size = ElementClass<type>::getShapeSize();
UInt lmat_size = nb_degree_of_freedom * shapes_size;
const Array<Real> & shapes = shape_functions.getShapes(type,ghost_type);
Array<Real> * modified_shapes = new Array<Real>(vect_size, lmat_size * nb_degree_of_freedom);
modified_shapes->clear();
Array<Real> * local_mat = new Array<Real>(vect_size, lmat_size * lmat_size);
Array<Real>::matrix_iterator mshapes_it = modified_shapes->begin(lmat_size, nb_degree_of_freedom);
Array<Real>::const_vector_iterator shapes_it = shapes.begin(shapes_size);
for(UInt q = 0; q < vect_size; ++q, ++mshapes_it, ++shapes_it) {
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
for (UInt s = 0; s < shapes_size; ++s) {
(*mshapes_it)(s*nb_degree_of_freedom + d, d) = (*shapes_it)(s);
}
}
}
mshapes_it = modified_shapes->begin(lmat_size, nb_degree_of_freedom);
Array<Real>::matrix_iterator lmat = local_mat->begin(lmat_size, lmat_size);
Array<Real>::const_scalar_iterator field_val = field_1.begin();
for(UInt q = 0; q < vect_size; ++q, ++lmat, ++mshapes_it, ++field_val) {
(*lmat).mul<false, true>(*mshapes_it, *mshapes_it, *field_val);
}
delete modified_shapes;
UInt nb_element = mesh.getNbElement(type, ghost_type);
Array<Real> * int_field_times_shapes = new Array<Real>(nb_element, lmat_size * lmat_size,
"inte_rho_x_shapes");
integrator.template integrate<type>(*local_mat, *int_field_times_shapes,
lmat_size * lmat_size, ghost_type, empty_filter);
delete local_mat;
assembleMatrix(*int_field_times_shapes, matrix, nb_degree_of_freedom, type, ghost_type);
delete int_field_times_shapes;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct InverseMapHelper {
template <class S>
static void call(const S & shape_functions,
const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
Vector<Real> & natural_coords,
const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define INVERSE_MAP(type) \
shape_functions.template inverseMap<type>(real_coords, element, natural_coords, ghost_type); \
#define AKANTU_SPECIALIZE_INVERSE_MAP_HELPER(kind) \
template<> \
struct InverseMapHelper<kind> { \
template <class S> \
static void call(const S & shape_functions, \
const Vector<Real> & real_coords, \
UInt element, \
const ElementType & type, \
Vector<Real> & natural_coords, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INVERSE_MAP, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INVERSE_MAP_HELPER, \
AKANTU_FE_ENGINE_LIST_INVERSE_MAP)
#undef AKANTU_SPECIALIZE_INVERSE_MAP_HELPER
#undef INVERSE_MAP
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::inverseMap(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
Vector<Real> & natural_coords,
const GhostType & ghost_type) const{
AKANTU_DEBUG_IN();
InverseMapHelper<kind>::call(shape_functions, real_coords, element, type, natural_coords, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct ContainsHelper {
template <class S>
static void call(const S & shape_functions,
const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define CONTAINS(type) \
contain = shape_functions.template contains<type>(real_coords, element, ghost_type); \
#define AKANTU_SPECIALIZE_CONTAINS_HELPER(kind) \
template<> \
struct ContainsHelper<kind> { \
template <template <ElementKind> class S, \
ElementKind k> \
static bool call(const S<k> & shape_functions, \
const Vector<Real> & real_coords, \
UInt element, \
const ElementType & type, \
const GhostType & ghost_type) { \
bool contain = false; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(CONTAINS, kind); \
return contain; \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_CONTAINS_HELPER, \
AKANTU_FE_ENGINE_LIST_CONTAINS)
#undef AKANTU_SPECIALIZE_CONTAINS_HELPER
#undef CONTAINS
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline bool FEEngineTemplate<I, S, kind>::contains(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
const GhostType & ghost_type) const{
return ContainsHelper<kind>::call(shape_functions, real_coords, element, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct ComputeShapesHelper {
template <class S>
static void call(const S & shape_functions,
const Vector<Real> & real_coords,
UInt element,
const ElementType type,
Vector<Real> & shapes,
const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define COMPUTE_SHAPES(type) \
shape_functions.template computeShapes<type>(real_coords, \
element, \
shapes, \
ghost_type);
#define AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER(kind) \
template<> \
struct ComputeShapesHelper<kind> { \
template <class S> \
static void call(const S & shape_functions, \
const Vector<Real> & real_coords, \
UInt element, \
const ElementType type, \
Vector<Real> & shapes, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_SHAPES, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER, \
AKANTU_FE_ENGINE_LIST_COMPUTE_SHAPES)
#undef AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER
#undef COMPUTE_SHAPES
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::computeShapes(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
Vector<Real> & shapes,
const GhostType & ghost_type) const{
AKANTU_DEBUG_IN();
ComputeShapesHelper<kind>::call(shape_functions, real_coords, element, type, shapes, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct ComputeShapeDerivativesHelper {
template <class S>
static void call(const S & shape_functions,
const Vector<Real> & real_coords,
UInt element,
const ElementType type,
Matrix<Real> & shape_derivatives,
const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define COMPUTE_SHAPE_DERIVATIVES(type) \
Matrix<Real> coords_mat(real_coords.storage(), shape_derivatives.rows(), 1); \
Tensor3<Real> shapesd_tensor(shape_derivatives.storage(), \
shape_derivatives.rows(), \
shape_derivatives.cols(), 1); \
shape_functions.template computeShapeDerivatives<type>(coords_mat, \
element, \
shapesd_tensor, \
ghost_type);
#define AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER(kind) \
template<> \
struct ComputeShapeDerivativesHelper<kind> { \
template <class S> \
static void call(const S & shape_functions, \
const Vector<Real> & real_coords, \
UInt element, \
const ElementType type, \
Matrix<Real> & shape_derivatives, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_SHAPE_DERIVATIVES, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER, \
AKANTU_FE_ENGINE_LIST_COMPUTE_SHAPES_DERIVATIVES)
#undef AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER
#undef COMPUTE_SHAPE_DERIVATIVES
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::computeShapeDerivatives(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
Matrix<Real> & shape_derivatives,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
ComputeShapeDerivativesHelper<kind>::call(shape_functions, real_coords, element, type, shape_derivatives, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct GetNbIntegrationPointsHelper { };
#define GET_NB_INTEGRATION_POINTS(type) \
nb_quad_points = \
integrator. template getQuadraturePoints<type>(ghost_type).cols();
#define AKANTU_SPECIALIZE_GET_NB_INTEGRATION_POINTS_HELPER(kind) \
template<> \
struct GetNbIntegrationPointsHelper<kind> { \
template <template <ElementKind> class I, \
ElementKind k> \
static UInt call(const I<k> & integrator, \
const ElementType type, \
const GhostType & ghost_type) { \
UInt nb_quad_points = 0; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_NB_INTEGRATION_POINTS, kind); \
return nb_quad_points; \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_NB_INTEGRATION_POINTS_HELPER)
#undef AKANTU_SPECIALIZE_GET_NB_INTEGRATION_POINTS_HELPER
#undef GET_NB_INTEGRATION
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline UInt FEEngineTemplate<I, S, kind>::getNbIntegrationPoints(const ElementType & type,
const GhostType & ghost_type) const {
return GetNbIntegrationPointsHelper<kind>::call(integrator, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct GetShapesHelper { };
#define GET_SHAPES(type) \
ret = &(shape_functions.getShapes(type, ghost_type));
#define AKANTU_SPECIALIZE_GET_SHAPES_HELPER(kind) \
template<> \
struct GetShapesHelper<kind> { \
template <class S> \
static const Array<Real> & call(const S& shape_functions, \
const ElementType type, \
const GhostType & ghost_type) { \
const Array<Real> * ret = NULL; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_SHAPES, kind); \
return *ret; \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_SHAPES_HELPER)
#undef AKANTU_SPECIALIZE_GET_SHAPES_HELPER
#undef GET_SHAPES
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline const Array<Real> & FEEngineTemplate<I, S, kind>::getShapes(const ElementType & type,
const GhostType & ghost_type,
__attribute__((unused)) UInt id) const {
return GetShapesHelper<kind>::call(shape_functions, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct GetShapesDerivativesHelper {
template <template <ElementKind> class S,
ElementKind k>
static const Array<Real> & call(const S<k> & shape_functions,
const ElementType & type,
const GhostType & ghost_type,
UInt id) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define GET_SHAPES_DERIVATIVES(type) \
ret = &(shape_functions.getShapesDerivatives(type, ghost_type));
#define AKANTU_SPECIALIZE_GET_SHAPES_DERIVATIVES_HELPER(kind) \
template<> \
struct GetShapesDerivativesHelper<kind> { \
template <template <ElementKind> class S, \
ElementKind k> \
static const Array<Real> & call(const S<k> & shape_functions, \
const ElementType type, \
const GhostType & ghost_type, \
UInt id) { \
const Array<Real> * ret = NULL; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_SHAPES_DERIVATIVES, kind); \
return *ret; \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_GET_SHAPES_DERIVATIVES_HELPER, \
AKANTU_FE_ENGINE_LIST_GET_SHAPES_DERIVATIVES)
#undef AKANTU_SPECIALIZE_GET_SHAPE_DERIVATIVES_HELPER
#undef GET_SHAPES_DERIVATIVES
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline const Array<Real> & FEEngineTemplate<I, S, kind>::getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type,
__attribute__((unused)) UInt id) const {
return GetShapesDerivativesHelper<kind>::call(shape_functions, type, ghost_type, id);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct GetIntegrationPointsHelper { };
#define GET_INTEGRATION_POINTS(type) \
ret = &(integrator. template getQuadraturePoints<type>(ghost_type)); \
#define AKANTU_SPECIALIZE_GET_INTEGRATION_POINTS_HELPER(kind) \
template<> \
struct GetIntegrationPointsHelper<kind> { \
template <template <ElementKind> class I, \
ElementKind k> \
static const Matrix<Real> & call(const I<k> & integrator, \
const ElementType type, \
const GhostType & ghost_type) { \
const Matrix<Real> * ret = NULL; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_INTEGRATION_POINTS, kind); \
return *ret; \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_INTEGRATION_POINTS_HELPER)
#undef AKANTU_SPECIALIZE_GET_INTEGRATION_POINTS_HELPER
#undef GET_INTEGRATION_POINTS
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline const Matrix<Real> &
FEEngineTemplate<I, S, kind>::getIntegrationPoints(const ElementType & type,
const GhostType & ghost_type) const {
return GetIntegrationPointsHelper<kind>::call(integrator, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "FEEngineTemplate [" << std::endl;
stream << space << " + parent [" << std::endl;
FEEngine::printself(stream, indent + 3);
stream << space << " ]" << std::endl;
stream << space << " + shape functions [" << std::endl;
shape_functions.printself(stream, indent + 3);
stream << space << " ]" << std::endl;
stream << space << " + integrator [" << std::endl;
integrator.printself(stream, indent + 3);
stream << space << " ]" << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include "shape_lagrange.hh"
#include "integrator_gauss.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_triangle_6>(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_triangle_6>(field_1, nb_degree_of_freedom,
lumped, equation_number, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_tetrahedron_10>(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_tetrahedron_10>(field_1, nb_degree_of_freedom,
lumped, equation_number, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_quadrangle_8>(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_quadrangle_8>(field_1, nb_degree_of_freedom,
lumped, equation_number, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_hexahedron_20>(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_hexahedron_20>(field_1, nb_degree_of_freedom,
lumped, equation_number, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_pentahedron_15>(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_pentahedron_15>(field_1, nb_degree_of_freedom,
lumped, equation_number, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<>
template<>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
computeNormalsOnIntegrationPoints<_point_1>(__attribute__((unused))const Array<Real> & field,
Array<Real> & normal,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == 1, "Mesh dimension must be 1 to compute normals on points!");
const ElementType type = _point_1;
UInt spatial_dimension = mesh.getSpatialDimension();
//UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_points = getNbIntegrationPoints(type, ghost_type);
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
normal.resize(nb_element * nb_points);
Array<Real>::matrix_iterator normals_on_quad = normal.begin_reinterpret(spatial_dimension,
nb_points,
nb_element);
Array< std::vector<Element> > segments = mesh.getElementToSubelement(type, ghost_type);
Array<Real> coords = mesh.getNodes();
const Mesh * mesh_segment;
if (mesh.isMeshFacets())
mesh_segment = &(mesh.getMeshParent());
else
mesh_segment = &mesh;
for (UInt elem = 0; elem < nb_element; ++elem) {
UInt nb_segment = segments(elem).size();
AKANTU_DEBUG_ASSERT(nb_segment > 0, "Impossible to compute a normal on a point connected to 0 segments");
Real normal_value = 1;
if (nb_segment == 1) {
Element segment = segments(elem)[0];
const Array<UInt> & segment_connectivity = mesh_segment->getConnectivity(segment.type, segment.ghost_type);
//const Vector<UInt> & segment_points = segment_connectivity.begin(Mesh::getNbNodesPerElement(segment.type))[segment.element];
Real difference;
if(segment_connectivity(0) == elem) {
difference = coords(elem)-coords(segment_connectivity(1));
} else {
difference = coords(elem)-coords(segment_connectivity(0));
}
normal_value = difference/std::abs(difference);
}
for(UInt n(0); n < nb_points; ++n) {
(*normals_on_quad)(0, n) = normal_value;
}
++normals_on_quad;
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/fe_engine/fe_engine_template_tmpl_struct.hh b/src/fe_engine/fe_engine_template_tmpl_struct.hh
index f7c273e6b..a829ad672 100644
--- a/src/fe_engine/fe_engine_template_tmpl_struct.hh
+++ b/src/fe_engine/fe_engine_template_tmpl_struct.hh
@@ -1,238 +1,239 @@
/**
* @file fe_engine_template_tmpl_struct.hh
*
- * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jul 07 2014
- * @date last modification: Mon Jul 07 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Template implementation of FEEngineTemplate for Structural Element Kinds
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "shape_linked.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <>
inline const Array<Real> &
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::
getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type,
UInt id) const {
AKANTU_DEBUG_IN();
const Array<Real> * ret = NULL;
#define GET_SHAPES(type) \
ret = &(shape_functions.getShapesDerivatives(type, ghost_type, id));
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_SHAPES);
#undef GET_SHAPES
AKANTU_DEBUG_OUT();
return *ret;
}
/* -------------------------------------------------------------------------- */
template<>
inline const Array<Real> &
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::getShapes(const ElementType & type,
const GhostType & ghost_type,
UInt id) const {
AKANTU_DEBUG_IN();
const Array<Real> * ret = NULL;
#define GET_SHAPES(type) \
ret = &(shape_functions.getShapes(type, ghost_type, id));
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_SHAPES);
#undef GET_SHAPES
AKANTU_DEBUG_OUT();
return *ret;
}
/* -------------------------------------------------------------------------- */
template<>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const ElementType & type,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
#define ASSEMBLE_MATRIX(type) \
assembleFieldMatrix<type>(field_1, nb_degree_of_freedom, \
M, n, rotation_mat, \
ghost_type)
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(ASSEMBLE_MATRIX);;
#undef ASSEMBLE_MATRIX
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::computeShapesMatrix(const ElementType & type,
UInt nb_degree_of_freedom,
UInt nb_nodes_per_element,
Array<Real> * n,
UInt id,
UInt degree_to_interpolate,
UInt degree_interpolated,
const bool sign,
const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template<>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::computeShapesMatrix(const ElementType & type,
UInt nb_degree_of_freedom,
UInt nb_nodes_per_element,
Array<Real> * n,
UInt id,
UInt degree_to_interpolate,
UInt degree_interpolated,
const bool sign, // true +, false -
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt nb_element = mesh.getNbElement(type);
UInt nb_quadrature_points = getNbIntegrationPoints(type);
UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
UInt n_size = n->getNbComponent()/nt_n_field_size;
Array<Real>::const_vector_iterator shape = getShapes(type, ghost_type, id).begin(nb_nodes_per_element);
Array<Real>::matrix_iterator N_it = n->begin(n_size , nt_n_field_size);
int c;
if (sign == true){
c=1;
}else{
c = -1;
}
UInt line = degree_interpolated;
UInt coll = degree_to_interpolate;
for (UInt e=0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quadrature_points; ++q, ++N_it, ++shape) {
const Vector<Real> & shapes = *shape;
Matrix<Real> & N = *N_it;
N(line, coll) = shapes(0) * c;
N(line, coll + nb_degree_of_freedom) = shapes(1) * c;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
template <ElementType type>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
UInt nb_quadrature_points = getNbIntegrationPoints(type);
UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
UInt n_size = n->getNbComponent()/nt_n_field_size;
Array<Real> * nt_n_field = new Array<Real>(nb_element * nb_quadrature_points, // nt_n_size * nt_n_size, nb_elem * nb_quad_points?
nt_n_field_size * nt_n_field_size,
"NT*N*field");
Array<Real> * nt = new Array<Real>(nb_element * nb_quadrature_points,
n_size * nt_n_field_size, "N*T");
Array<Real> t = rotation_mat(type);
nt_n_field->clear();
nt->clear();
Array<Real>::matrix_iterator N = n->begin(n_size, nt_n_field_size);
Array<Real>::matrix_iterator Nt_N_field = nt_n_field->begin(nt_n_field_size, nt_n_field_size);
Array<Real>::matrix_iterator T = rotation_mat(type).begin(nt_n_field_size, nt_n_field_size);
Array<Real>::matrix_iterator NT = nt->begin(n_size, nt_n_field_size);
Real * field_val = field_1.storage();
for (UInt e = 0; e < nb_element; ++e, ++T){
for (UInt q = 0; q< nb_quadrature_points; ++q, ++N, ++NT, ++Nt_N_field, /*++T,*/ ++field_val){
NT->mul<false, false>(*N, *T);
Nt_N_field->mul<true, false>(*NT, *NT, *field_val);
}
}
Array<Real> * int_nt_n_field = new Array<Real>(nb_element,
nt_n_field_size * nt_n_field_size,
"NT*N*field");
int_nt_n_field->clear();
integrate(*nt_n_field, *int_nt_n_field, nt_n_field_size * nt_n_field_size, type);
// integrate(*nt_n_field, *int_nt_n_field, nb_degree_of_freedom, type);
assembleMatrix(*int_nt_n_field, M, nb_degree_of_freedom, type);
delete nt;
delete nt_n_field;
delete int_nt_n_field;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
inline void FEEngineTemplate<I, S, kind>::assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
__END_AKANTU__
diff --git a/src/fe_engine/geometrical_element.cc b/src/fe_engine/geometrical_element.cc
index b3354e0c3..1e6f5dc9c 100644
--- a/src/fe_engine/geometrical_element.cc
+++ b/src/fe_engine/geometrical_element.cc
@@ -1,204 +1,205 @@
-
-// A CHECKER PAR LAFFFELY A RECHECK PAR SCANTEUM (Damien : j'ai checker hexaedron_20 et petahedron_15,osef du pentahedron_6)
-/**
+/**
* @file geometrical_element.cc
*
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Thomas Menouillard <tmenouillard@stucky.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date Wed Nov 14 14:57:27 2012
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sat Sep 12 2015
*
* @brief Specialization of the geometrical types
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "element_class.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_not_defined>::spatial_dimension = 0;
template<> UInt GeometricalElement<_gt_not_defined>::nb_nodes_per_element = 0;
template<> UInt GeometricalElement<_gt_not_defined>::nb_facets[] = { 0 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_point>::spatial_dimension = 0;
template<> UInt GeometricalElement<_gt_point>::nb_nodes_per_element = 1;
template<> UInt GeometricalElement<_gt_point>::nb_facets[] = { 1 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_segment_2>::spatial_dimension = 1;
template<> UInt GeometricalElement<_gt_segment_2>::nb_nodes_per_element = 2;
template<> UInt GeometricalElement<_gt_segment_2>::nb_facets[] = { 2 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_segment_3>::spatial_dimension = 1;
template<> UInt GeometricalElement<_gt_segment_3>::nb_nodes_per_element = 3;
template<> UInt GeometricalElement<_gt_segment_3>::nb_facets[] = { 2 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_triangle_3>::spatial_dimension = 2;
template<> UInt GeometricalElement<_gt_triangle_3>::nb_nodes_per_element = 3;
template<> UInt GeometricalElement<_gt_triangle_3>::nb_facets[] = { 3 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_triangle_6>::spatial_dimension = 2;
template<> UInt GeometricalElement<_gt_triangle_6>::nb_nodes_per_element = 6;
template<> UInt GeometricalElement<_gt_triangle_6>::nb_facets[] = { 3 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_tetrahedron_4>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_tetrahedron_4>::nb_nodes_per_element = 4;
template<> UInt GeometricalElement<_gt_tetrahedron_4>::nb_facets[] = { 4 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_tetrahedron_10>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_tetrahedron_10>::nb_nodes_per_element = 10;
template<> UInt GeometricalElement<_gt_tetrahedron_10>::nb_facets[] = { 4 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_quadrangle_4>::spatial_dimension = 2;
template<> UInt GeometricalElement<_gt_quadrangle_4>::nb_nodes_per_element = 4;
template<> UInt GeometricalElement<_gt_quadrangle_4>::nb_facets[] = { 4 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_quadrangle_8>::spatial_dimension = 2;
template<> UInt GeometricalElement<_gt_quadrangle_8>::nb_nodes_per_element = 8;
template<> UInt GeometricalElement<_gt_quadrangle_8>::nb_facets[] = { 4 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_hexahedron_8>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_hexahedron_8>::nb_nodes_per_element = 8;
template<> UInt GeometricalElement<_gt_hexahedron_8>::nb_facets[] = { 6 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_hexahedron_20>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_hexahedron_20>::nb_nodes_per_element = 20;
template<> UInt GeometricalElement<_gt_hexahedron_20>::nb_facets[] = { 6 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_pentahedron_6>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_pentahedron_6>::nb_nodes_per_element = 6;
template<> UInt GeometricalElement<_gt_pentahedron_6>::nb_facets[] = { 2, 3 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_pentahedron_15>::spatial_dimension = 3;
template<> UInt GeometricalElement<_gt_pentahedron_15>::nb_nodes_per_element = 15;
template<> UInt GeometricalElement<_gt_pentahedron_15>::nb_facets[] = { 2, 3 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_not_defined>::nb_nodes_per_facet[] = { 0 };
template<> UInt GeometricalElement<_gt_point>::nb_nodes_per_facet[] = { 1 };
template<> UInt GeometricalElement<_gt_segment_2>::nb_nodes_per_facet[] = { 1 };
template<> UInt GeometricalElement<_gt_segment_3>::nb_nodes_per_facet[] = { 1 };
template<> UInt GeometricalElement<_gt_triangle_3>::nb_nodes_per_facet[] = { 2 };
template<> UInt GeometricalElement<_gt_triangle_6>::nb_nodes_per_facet[] = { 3 };
template<> UInt GeometricalElement<_gt_tetrahedron_4>::nb_nodes_per_facet[] = { 3 };
template<> UInt GeometricalElement<_gt_tetrahedron_10>::nb_nodes_per_facet[] = { 6 };
template<> UInt GeometricalElement<_gt_quadrangle_4>::nb_nodes_per_facet[] = { 2 };
template<> UInt GeometricalElement<_gt_quadrangle_8>::nb_nodes_per_facet[] = { 3 };
template<> UInt GeometricalElement<_gt_hexahedron_8>::nb_nodes_per_facet[] = { 4 };
template<> UInt GeometricalElement<_gt_hexahedron_20>::nb_nodes_per_facet[] = { 8 };
template<> UInt GeometricalElement<_gt_pentahedron_6>::nb_nodes_per_facet[] = { 3, 4 };
template<> UInt GeometricalElement<_gt_pentahedron_15>::nb_nodes_per_facet[] = { 6, 8 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_not_defined>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_point>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_segment_2>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_segment_3>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_triangle_3>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_triangle_6>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_tetrahedron_4>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_tetrahedron_10>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_quadrangle_4>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_quadrangle_8>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_hexahedron_8>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_hexahedron_20>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_pentahedron_6>::nb_facet_types = 2;
template<> UInt GeometricalElement<_gt_pentahedron_15>::nb_facet_types = 2;
/* !!! stored as a matrix nb_facets X nb_nodes_per_facet in COL MAJOR */
/* -------------------------------------------------------------------------- */
/* f1|f2|f3|f4|f5|f6 */
template<> UInt GeometricalElement<_gt_not_defined>::facet_connectivity_vect[] = {};
template<> UInt GeometricalElement<_gt_point>::facet_connectivity_vect[] = {0};
template<> UInt GeometricalElement<_gt_segment_2>::facet_connectivity_vect[] = {0, 1};
template<> UInt GeometricalElement<_gt_segment_3>::facet_connectivity_vect[] = {0, 1};
template<> UInt GeometricalElement<_gt_triangle_3>::facet_connectivity_vect[] = {0, 1, 2,
1, 2, 0};
template<> UInt GeometricalElement<_gt_triangle_6>::facet_connectivity_vect[] = {0, 1, 2,
1, 2, 0,
3, 4, 5};
template<> UInt GeometricalElement<_gt_tetrahedron_4>::facet_connectivity_vect[] = {0, 1, 2, 0,
2, 2, 0, 1,
1, 3, 3, 3};
template<> UInt GeometricalElement<_gt_tetrahedron_10>::facet_connectivity_vect[] = {0, 1, 2, 0,
2, 2, 0, 1,
1, 3, 3, 3,
6, 5, 6, 4,
5, 9, 7, 8,
4, 8, 9, 7};
template<> UInt GeometricalElement<_gt_quadrangle_4>::facet_connectivity_vect[] = {0, 1, 2, 3,
1, 2, 3, 0};
template<> UInt GeometricalElement<_gt_quadrangle_8>::facet_connectivity_vect[] = {0, 1, 2, 3,
1, 2, 3, 0,
4, 5, 6, 7};
template<> UInt GeometricalElement<_gt_hexahedron_8>::facet_connectivity_vect[] = {0, 0, 1, 2, 3, 4,
3, 1, 2, 3, 0, 5,
2, 5, 6, 7, 4, 6,
1, 4, 5, 6, 7, 7};
template<> UInt GeometricalElement<_gt_hexahedron_20>::facet_connectivity_vect[] = {0, 1, 2, 3, 0, 4,
1, 2, 3, 0, 3, 5,
5, 6, 7, 4, 2, 6,
4, 5, 6, 7, 1, 7,
8, 9, 10, 11, 11, 16,
13, 14, 15, 12, 10, 17,
16, 17, 18, 19, 9, 18,
12, 13, 14, 15, 8, 19};
template<> UInt GeometricalElement<_gt_pentahedron_6>::facet_connectivity_vect[] = {// first type
0, 3,
2, 4,
1, 5,
// second type
0, 0, 1,
1, 3, 2,
4, 5, 5,
3, 2, 4};
template<> UInt GeometricalElement<_gt_pentahedron_15>::facet_connectivity_vect[] = {// first type
0, 3,
2, 4,
1, 5,
8, 12,
7, 13,
6, 14,
// second type
0, 0, 1,
1, 3, 2,
4, 5, 5,
3, 2, 4,
6, 9, 7,
10, 14, 11,
12, 11, 13,
9, 8, 10};
template<> UInt * GeometricalElement<_gt_not_defined>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_point>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_segment_2>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_segment_3>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_triangle_3>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_triangle_6>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_tetrahedron_4>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_tetrahedron_10>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_quadrangle_4>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_quadrangle_8>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_hexahedron_8>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_hexahedron_20>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_pentahedron_6>::facet_connectivity[] = { &facet_connectivity_vect[0], &facet_connectivity_vect[2*3] };
template<> UInt * GeometricalElement<_gt_pentahedron_15>::facet_connectivity[] = { &facet_connectivity_vect[0], &facet_connectivity_vect[2*6] };
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/fe_engine/integration_element.cc b/src/fe_engine/integration_element.cc
index cbcbcef88..261ff32ec 100644
--- a/src/fe_engine/integration_element.cc
+++ b/src/fe_engine/integration_element.cc
@@ -1,132 +1,135 @@
/**
* @file integration_element.cc
*
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
+ * @author Thomas Menouillard <tmenouillard@stucky.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Mon Jul 07 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Thu Nov 05 2015
*
* @brief Definition of the integration constants
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "element_class.hh"
using std::sqrt;
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Points */
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_point, 1>::nb_quadrature_points = 1;
template<> Real GaussIntegrationTypeData<_git_point, 1>::quad_positions[] = {0};
template<> Real GaussIntegrationTypeData<_git_point, 1>::quad_weights[] = {1.};
/* -------------------------------------------------------------------------- */
/* Segments */
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_segment, 1>::nb_quadrature_points = 1;
template<> Real GaussIntegrationTypeData<_git_segment, 1>::quad_positions[] = {0.};
template<> Real GaussIntegrationTypeData<_git_segment, 1>::quad_weights[] = {2.};
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_segment, 2>::nb_quadrature_points = 2;
template<> Real GaussIntegrationTypeData<_git_segment, 2>::quad_positions[] = {-1./sqrt(3.), 1./sqrt(3.)};
template<> Real GaussIntegrationTypeData<_git_segment, 2>::quad_weights[] = {1., 1.};
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_segment, 3>::nb_quadrature_points = 3;
template<> Real GaussIntegrationTypeData<_git_segment, 3>::quad_positions[] = {-sqrt(3./5.), 0., sqrt(3./5.)};
template<> Real GaussIntegrationTypeData<_git_segment, 3>::quad_weights[] = {5./9., 8./9., 5./9.};
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_segment, 4>::nb_quadrature_points = 4;
template<> Real GaussIntegrationTypeData<_git_segment, 4>::quad_positions[] = {-sqrt((3. + 2.*sqrt(6./5.))/7.),
-sqrt((3. - 2.*sqrt(6./5.))/7.),
sqrt((3. - 2.*sqrt(6./5.))/7.),
sqrt((3. + 2.*sqrt(6./5.))/7.)};
template<> Real GaussIntegrationTypeData<_git_segment, 4>::quad_weights[] = {(18. - sqrt(30.))/36.,
(18. + sqrt(30.))/36.,
(18. + sqrt(30.))/36.,
(18. - sqrt(30.))/36.};
/* -------------------------------------------------------------------------- */
/* Triangles */
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_triangle, 1>::nb_quadrature_points = 1;
template<> Real GaussIntegrationTypeData<_git_triangle, 1>::quad_positions[] = {1./3., 1./3.};
template<> Real GaussIntegrationTypeData<_git_triangle, 1>::quad_weights[] = {1./2.};
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_triangle, 2>::nb_quadrature_points = 3;
template<> Real GaussIntegrationTypeData<_git_triangle, 2>::quad_positions[] = {1./6., 1./6.,
2./3., 1./6.,
1./6., 2./3.};
template<> Real GaussIntegrationTypeData<_git_triangle, 2>::quad_weights[] = {1./6., 1./6., 1./6.};
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_triangle, 3>::nb_quadrature_points = 4;
template<> Real GaussIntegrationTypeData<_git_triangle, 3>::quad_positions[] = {1./5., 1./5.,
3./5., 1./5.,
1./5., 3./5.,
1./3., 1./3.};
template<> Real GaussIntegrationTypeData<_git_triangle, 3>::quad_weights[] = {25./(24.*4.), 25./(24.*4.), 25./(24.*4.), -27/(24.*4.)};
/* -------------------------------------------------------------------------- */
/* Tetrahedrons */
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_tetrahedron, 1>::nb_quadrature_points = 1;
template<> Real GaussIntegrationTypeData<_git_tetrahedron, 1>::quad_positions[] = {1./4., 1./4., 1./4.};
template<> Real GaussIntegrationTypeData<_git_tetrahedron, 1>::quad_weights[] = {1./6.};
/* -------------------------------------------------------------------------- */
static const Real tet_2_a = (5. - std::sqrt(5.))/20.;
static const Real tet_2_b = (5. + 3.*std::sqrt(5.))/20.;
template<> UInt GaussIntegrationTypeData<_git_tetrahedron, 2>::nb_quadrature_points = 4;
template<> Real GaussIntegrationTypeData<_git_tetrahedron, 2>::quad_positions[] = {tet_2_a, tet_2_a, tet_2_a,
tet_2_b, tet_2_a, tet_2_a,
tet_2_a, tet_2_b, tet_2_a,
tet_2_a, tet_2_a, tet_2_b};
template<> Real GaussIntegrationTypeData<_git_tetrahedron, 2>::quad_weights[] = {1./24., 1./24., 1./24., 1./24.};
/* -------------------------------------------------------------------------- */
/* Pentahedrons */
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_pentahedron, 1>::nb_quadrature_points = 6;
template<> Real GaussIntegrationTypeData<_git_pentahedron, 1>::quad_positions[] = {-1./sqrt(3.), 0.5, 0.5,
-1./sqrt(3.), 0. , 0.5,
-1./sqrt(3.), 0.5, 0.,
1./sqrt(3.), 0.5, 0.5,
1./sqrt(3.), 0. , 0.5,
1./sqrt(3.), 0.5 ,0.};
template<> Real GaussIntegrationTypeData<_git_pentahedron, 1>::quad_weights[] = {1./6., 1./6., 1./6.,
1./6., 1./6., 1./6.};
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_pentahedron, 2>::nb_quadrature_points = 8;
template<> Real GaussIntegrationTypeData<_git_pentahedron, 2>::quad_positions[] = {-sqrt(3.)/3., 1./3., 1./3.,
-sqrt(3.)/3., 0.6 , 0.2,
-sqrt(3.)/3., 0.2, 0.6,
-sqrt(3.)/3., 0.2, 0.2,
sqrt(3.)/3., 1./3., 1./3.,
sqrt(3.)/3., 0.6 , 0.2,
sqrt(3.)/3., 0.2, 0.6,
sqrt(3.)/3., 0.2, 0.2};
template<> Real GaussIntegrationTypeData<_git_pentahedron, 2>::quad_weights[] = {-27./96., 25./96., 25./96., 25./96.,
-27./96., 25./96., 25./96., 25./96.};
__END_AKANTU__
diff --git a/src/fe_engine/integration_point.hh b/src/fe_engine/integration_point.hh
index c3c713bc1..672fadadb 100644
--- a/src/fe_engine/integration_point.hh
+++ b/src/fe_engine/integration_point.hh
@@ -1,157 +1,156 @@
/**
* @file integration_point.hh
*
- * @author
*
- * @date creation:
- * @date last modification: Mon Oct 19 2015
+ * @date creation: Wed Jun 17 2015
+ * @date last modification: Sun Nov 15 2015
*
* @brief definition of the class IntegrationPoint
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef AKANTU_QUADRATURE_POINT_H
#define AKANTU_QUADRATURE_POINT_H
/* -------------------------------------------------------------------------- */
#include "element.hh"
#include "aka_types.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class IntegrationPoint;
extern const IntegrationPoint IntegrationPointNull;
/* -------------------------------------------------------------------------- */
class IntegrationPoint : public Element {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef Vector<Real> position_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
IntegrationPoint(const Element & element, UInt num_point = 0, UInt nb_quad_per_element = 0) :
Element(element), num_point(num_point),
global_num(element.element*nb_quad_per_element + num_point),
position((Real *)NULL, 0) { };
IntegrationPoint(ElementType type = _not_defined, UInt element = 0,
UInt num_point = 0, GhostType ghost_type = _not_ghost) :
Element(type, element, ghost_type), num_point(num_point), global_num(0),
position((Real *)NULL, 0) { };
IntegrationPoint(UInt element, UInt num_point,
UInt global_num,
const position_type & position,
ElementType type,
GhostType ghost_type = _not_ghost) :
Element(type, element, ghost_type), num_point(num_point), global_num(global_num),
position((Real *)NULL, 0) { this->position.shallowCopy(position); };
IntegrationPoint(const IntegrationPoint & quad) :
Element(quad), num_point(quad.num_point), global_num(quad.global_num), position((Real *) NULL, 0) {
position.shallowCopy(quad.position);
};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
inline bool operator==(const IntegrationPoint & quad) const {
return Element::operator==(quad) && this->num_point == quad.num_point;
}
inline bool operator!=(const IntegrationPoint & quad) const {
return ((element != quad.element)
|| (type != quad.type)
|| (ghost_type != quad.ghost_type)
|| (kind != quad.kind)
|| (num_point != quad.num_point)
|| (global_num != quad.global_num));
}
bool operator<(const IntegrationPoint& rhs) const {
bool res = Element::operator<(rhs) || (Element::operator==(rhs) && this->num_point < rhs.num_point);
return res;
}
inline IntegrationPoint & operator=(const IntegrationPoint & q) {
if(this != &q) {
element = q.element;
type = q.type;
ghost_type = q.ghost_type;
num_point = q.num_point;
global_num = q.global_num;
position.shallowCopy(q.position);
}
return *this;
}
/// get the position of the integration point
AKANTU_GET_MACRO(Position, position, const position_type &);
/// set the position of the integration point
void setPosition(const position_type & position) {
this->position.shallowCopy(position);
}
/// deep copy of the position of the integration point
void copyPosition(const position_type & position) {
this->position.deepCopy(position);
}
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "IntegrationPoint [";
Element::printself(stream, 0);
stream << ", " << num_point << "(" << global_num << ")" << "]";
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
/// number of quadrature point in the element
UInt num_point;
/// global number of the quadrature point
UInt global_num;
// TODO might be temporary: however this class should be tought maybe...
std::string material_id;
private:
/// position of the quadrature point
position_type position;
};
__END_AKANTU__
#endif /* AKANTU_QUADRATURE_POINT_H */
diff --git a/src/fe_engine/integrator.hh b/src/fe_engine/integrator.hh
index 933445da0..26c606e9d 100644
--- a/src/fe_engine/integrator.hh
+++ b/src/fe_engine/integrator.hh
@@ -1,133 +1,135 @@
/**
* @file integrator.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Feb 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 22 2015
*
* @brief interface for integrator classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
#ifndef __AKANTU_INTEGRATOR_HH__
#define __AKANTU_INTEGRATOR_HH__
/* -------------------------------------------------------------------------- */
#include "aka_memory.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class Integrator : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Integrator(const Mesh & mesh,
const ID & id="integrator",
const MemoryID & memory_id = 0) :
Memory(id, memory_id),
mesh(mesh),
jacobians("jacobians", id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
};
virtual ~Integrator(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// empty method
template <ElementType type>
inline void precomputeJacobiansOnQuadraturePoints(__attribute__ ((unused))
GhostType ghost_type){}
/// empty method
void integrateOnElement(__attribute__ ((unused)) const Array<Real> & f,
__attribute__ ((unused)) Real * intf,
__attribute__ ((unused)) UInt nb_degree_of_freedom,
__attribute__ ((unused)) const Element & elem,
__attribute__ ((unused)) GhostType ghost_type) const {};
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Integrator [" << std::endl;
jacobians.printself(stream, indent + 1);
stream << space << "]" << std::endl;
};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// access to the jacobians
Array<Real> & getJacobians(const ElementType & type,
const GhostType & ghost_type = _not_ghost) {
return jacobians(type, ghost_type);
};
/// access to the jacobians const
const Array<Real> & getJacobians(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
return jacobians(type, ghost_type);
};
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// mesh associated to the integrator
const Mesh & mesh;
/// jacobians for all elements
ElementTypeMapArray<Real> jacobians;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "integrator_inline_impl.cc"
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const Integrator & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_INTEGRATOR_HH__ */
diff --git a/src/fe_engine/integrator_gauss.hh b/src/fe_engine/integrator_gauss.hh
index 9df81f94c..25a1ea121 100644
--- a/src/fe_engine/integrator_gauss.hh
+++ b/src/fe_engine/integrator_gauss.hh
@@ -1,151 +1,152 @@
/**
* @file integrator_gauss.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Feb 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 22 2015
*
* @brief Gauss integration facilities
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
#ifndef __AKANTU_INTEGRATOR_GAUSS_HH__
#define __AKANTU_INTEGRATOR_GAUSS_HH__
/* -------------------------------------------------------------------------- */
#include "integrator.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
template<ElementKind kind>
class IntegratorGauss : public Integrator {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
IntegratorGauss(const Mesh & mesh,
const ID & id = "integrator_gauss",
const MemoryID & memory_id = 0);
virtual ~IntegratorGauss(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline void initIntegrator(const Array<Real> & nodes,
const ElementType & type,
const GhostType & ghost_type);
/// precompute jacobians on elements of type "type"
template <ElementType type>
void precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
const GhostType & ghost_type);
// multiply the jacobians by the integration weights and stores the results in jacobians
template <ElementType type>
void multiplyJacobiansByWeights(const GhostType & ghost_type);
/// integrate f on the element "elem" of type "type"
template <ElementType type>
inline void integrateOnElement(const Array<Real> & f,
Real * intf,
UInt nb_degree_of_freedom,
const UInt elem,
const GhostType & ghost_type) const;
/// integrate f for all elements of type "type"
template <ElementType type>
void integrate(const Array<Real> & in_f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/// integrate one element scalar value on all elements of type "type"
template <ElementType type>
Real integrate(const Vector<Real> & in_f,
UInt index,
const GhostType & ghost_type) const;
/// integrate scalar field in_f
template <ElementType type>
Real integrate(const Array<Real> & in_f,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/// integrate partially around a quadrature point (@f$ intf_q = f_q * J_q * w_q @f$)
template <ElementType type>
void integrateOnQuadraturePoints(const Array<Real> & in_f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/// return a vector with quadrature points natural coordinates
template <ElementType type>
const Matrix<Real> & getQuadraturePoints(const GhostType & ghost_type) const;
/// compute the vector of quadrature points natural coordinates
template <ElementType type> void computeQuadraturePoints(const GhostType & ghost_type);
/// check that the jacobians are not negative
template <ElementType type> void checkJacobians(const GhostType & ghost_type) const;
public:
/// compute the jacobians on quad points for a given element
template <ElementType type>
void computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
Vector<Real> & jacobians);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// integrate the field f with the jacobian jac -> inte
inline void integrate(Real *f, Real *jac, Real * inte,
UInt nb_degree_of_freedom,
UInt nb_quadrature_points) const;
private:
/// ElementTypeMap of the quadrature points
ElementTypeMap< Matrix<Real> > quadrature_points;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "integrator_gauss_inline_impl.cc"
#endif
__END_AKANTU__
#endif /* __AKANTU_INTEGRATOR_GAUSS_HH__ */
diff --git a/src/fe_engine/integrator_gauss_inline_impl.cc b/src/fe_engine/integrator_gauss_inline_impl.cc
index fdce1fcf0..b2d62007e 100644
--- a/src/fe_engine/integrator_gauss_inline_impl.cc
+++ b/src/fe_engine/integrator_gauss_inline_impl.cc
@@ -1,500 +1,501 @@
/**
* @file integrator_gauss_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Feb 15 2011
- * @date last modification: Mon Jun 23 2014
+ * @date last modification: Thu Nov 19 2015
*
* @brief inline function of gauss integrator
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
__END_AKANTU__
#include "fe_engine.hh"
#if defined(AKANTU_DEBUG_TOOLS)
# include "aka_debug_tools.hh"
#endif
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
inline void IntegratorGauss<kind>::integrateOnElement(const Array<Real> & f,
Real * intf,
UInt nb_degree_of_freedom,
const UInt elem,
const GhostType & ghost_type) const {
Array<Real> & jac_loc = jacobians(type, ghost_type);
UInt nb_quadrature_points = ElementClass<type>::getNbQuadraturePoints();
AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom ,
"The vector f do not have the good number of component.");
Real * f_val = f.storage() + elem * f.getNbComponent();
Real * jac_val = jac_loc.storage() + elem * nb_quadrature_points;
integrate(f_val, jac_val, intf, nb_degree_of_freedom, nb_quadrature_points);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
inline Real IntegratorGauss<kind>::integrate(const Vector<Real> & in_f,
UInt index,
const GhostType & ghost_type) const {
const Array<Real> & jac_loc = jacobians(type, ghost_type);
UInt nb_quadrature_points = GaussIntegrationElement<type>::getNbQuadraturePoints();
AKANTU_DEBUG_ASSERT(in_f.size() == nb_quadrature_points ,
"The vector f do not have nb_quadrature_points entries.");
Real * jac_val = jac_loc.storage() + index * nb_quadrature_points;
Real intf;
integrate(in_f.storage(), jac_val, &intf, 1, nb_quadrature_points);
return intf;
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
inline void IntegratorGauss<kind>::integrate(Real *f, Real *jac, Real * inte,
UInt nb_degree_of_freedom,
UInt nb_quadrature_points) const {
memset(inte, 0, nb_degree_of_freedom * sizeof(Real));
Real *cjac = jac;
for (UInt q = 0; q < nb_quadrature_points; ++q) {
for (UInt dof = 0; dof < nb_degree_of_freedom; ++dof) {
inte[dof] += *f * *cjac;
++f;
}
++cjac;
}
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
inline const Matrix<Real> & IntegratorGauss<kind>::getQuadraturePoints(const GhostType & ghost_type) const {
AKANTU_DEBUG_ASSERT(quadrature_points.exists(type, ghost_type),
"Quadrature points for type "
<< quadrature_points.printType(type, ghost_type)
<< " have not been initialized."
<< " Did you use 'computeQuadraturePoints' function ?");
return quadrature_points(type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
inline void IntegratorGauss<kind>::computeQuadraturePoints(const GhostType & ghost_type) {
Matrix<Real> & quads = quadrature_points(type, ghost_type);
quads = GaussIntegrationElement<type>::getQuadraturePoints();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
inline void IntegratorGauss<kind>::
computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
Vector<Real> & jacobians) {
Matrix<Real> quad = GaussIntegrationElement<type>::getQuadraturePoints();
// jacobian
ElementClass<type>::computeJacobian(quad, node_coords, jacobians);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
IntegratorGauss<kind>::IntegratorGauss(const Mesh & mesh,
const ID & id,
const MemoryID & memory_id) :
Integrator(mesh, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void IntegratorGauss<kind>::checkJacobians(const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points = GaussIntegrationElement<type>::getNbQuadraturePoints();
UInt nb_element;
nb_element = mesh.getConnectivity(type,ghost_type).getSize();
Real * jacobians_val = jacobians(type, ghost_type).storage();
for (UInt i = 0; i < nb_element*nb_quadrature_points; ++i,++jacobians_val){
if(*jacobians_val < 0)
AKANTU_DEBUG_ERROR("Negative jacobian computed,"
<< " possible problem in the element node ordering (Quadrature Point "
<< i % nb_quadrature_points << ":"
<< i / nb_quadrature_points << ":"
<< type << ":"
<< ghost_type << ")");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void IntegratorGauss<kind>::precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = GaussIntegrationElement<type>::getNbQuadraturePoints();
UInt nb_element = mesh.getNbElement(type,ghost_type);
Array<Real> * jacobians_tmp;
if(!jacobians.exists(type, ghost_type))
jacobians_tmp = &jacobians.alloc(nb_element*nb_quadrature_points,
1,
type,
ghost_type);
else {
jacobians_tmp = &jacobians(type, ghost_type);
jacobians_tmp->resize(nb_element*nb_quadrature_points);
}
Array<Real>::vector_iterator jacobians_it =
jacobians_tmp->begin_reinterpret(nb_quadrature_points, nb_element);
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
Array<Real>::const_matrix_iterator x_it = x_el.begin(spatial_dimension,
nb_nodes_per_element);
// Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++jacobians_it, ++x_it) {
const Matrix<Real> & x = *x_it;
Vector<Real> & J = *jacobians_it;
computeJacobianOnQuadPointsByElement<type>(x, J);
}
// >>>>>> DEBUG CODE >>>>>> //
#if defined(AKANTU_DEBUG_TOOLS)
#if defined(AKANTU_CORE_CXX11)
debug::element_manager.print(debug::_dm_integrator,
[ghost_type, this,
nb_element, nb_quadrature_points](const Element & el)->std::string {
std::stringstream out;
if(el.ghost_type == ghost_type) {
Array<Real>::vector_iterator jacobians_it =
jacobians(el.type, el.ghost_type).begin(nb_quadrature_points);
out << " jacobian: " << Vector<Real>(jacobians_it[el.element]);
}
return out.str();
});
#endif
#endif
// <<<<<< DEBUG CODE <<<<<< //
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void IntegratorGauss<kind>::multiplyJacobiansByWeights(const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points = GaussIntegrationElement<type>::getNbQuadraturePoints();
UInt nb_element = this->mesh.getNbElement(type, ghost_type);
Vector<Real> weights = GaussIntegrationElement<type>::getWeights();
Array<Real>::vector_iterator jacobians_it =
this->jacobians(type, ghost_type).begin_reinterpret(nb_quadrature_points, nb_element);
Array<Real>::vector_iterator jacobians_end =
this->jacobians(type, ghost_type).end_reinterpret(nb_quadrature_points, nb_element);
for (; jacobians_it != jacobians_end; ++jacobians_it) {
Vector<Real> & J = *jacobians_it;
J *= weights;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_COHESIVE_ELEMENT)
template <>
template <ElementType type>
void IntegratorGauss<_ek_cohesive>::precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = GaussIntegrationElement<type>::getNbQuadraturePoints();
UInt nb_element = mesh.getNbElement(type,ghost_type);
Array<Real> * jacobians_tmp;
if(!jacobians.exists(type, ghost_type))
jacobians_tmp = &jacobians.alloc(nb_element*nb_quadrature_points,
1,
type,
ghost_type);
else {
jacobians_tmp = &jacobians(type, ghost_type);
jacobians_tmp->resize(nb_element*nb_quadrature_points);
}
Array<Real>::vector_iterator jacobians_it =
jacobians_tmp->begin_reinterpret(nb_quadrature_points, nb_element);
Vector<Real> weights = GaussIntegrationElement<type>::getWeights();
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
Array<Real>::const_matrix_iterator x_it = x_el.begin(spatial_dimension,
nb_nodes_per_element);
UInt nb_nodes_per_subelement = nb_nodes_per_element / 2;
Matrix<Real> x(spatial_dimension, nb_nodes_per_subelement);
// Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++jacobians_it, ++x_it) {
for (UInt s = 0; s < spatial_dimension; ++s)
for (UInt n = 0; n < nb_nodes_per_subelement; ++n)
x(s, n) = ((*x_it)(s, n) + (*x_it)(s, n + nb_nodes_per_subelement))*.5;
Vector<Real> & J = *jacobians_it;
if (type == _cohesive_1d_2)
J(0) = 1;
else
computeJacobianOnQuadPointsByElement<type>(x, J);
}
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void IntegratorGauss<kind>::integrate(const Array<Real> & in_f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
"No jacobians for the type "
<< jacobians.printType(type, ghost_type));
UInt nb_points = GaussIntegrationElement<type>::getNbQuadraturePoints();
const Array<Real> & jac_loc = jacobians(type, ghost_type);
Array<Real>::const_matrix_iterator J_it;
Array<Real>::matrix_iterator inte_it;
Array<Real>::const_matrix_iterator f_it;
UInt nb_element;
Array<Real> * filtered_J = NULL;
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type, filter_elements);
const Array<Real> & cfiltered_J = *filtered_J; // \todo temporary patch
J_it = cfiltered_J.begin_reinterpret(nb_points, 1, nb_element);
} else {
nb_element = mesh.getNbElement(type,ghost_type);
J_it = jac_loc.begin_reinterpret(nb_points, 1, nb_element);
}
intf.resize(nb_element);
f_it = in_f.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element);
inte_it = intf.begin_reinterpret(nb_degree_of_freedom, 1, nb_element);
for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
const Matrix<Real> & f = *f_it;
const Matrix<Real> & J = *J_it;
Matrix<Real> & inte_f = *inte_it;
inte_f.mul<false, false>(f, J);
}
delete filtered_J;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
Real IntegratorGauss<kind>::integrate(const Array<Real> & in_f,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
"No jacobians for the type "
<< jacobians.printType(type, ghost_type));
Array<Real> intfv(0, 1);
integrate<type>(in_f, intfv, 1, ghost_type, filter_elements);
UInt nb_values = intfv.getSize();
if(nb_values == 0) return 0.;
UInt nb_values_to_sum = nb_values >> 1;
std::sort(intfv.begin(), intfv.end());
// as long as the half is not empty
while(nb_values_to_sum) {
UInt remaining = (nb_values - 2*nb_values_to_sum);
if(remaining) intfv(nb_values - 2) += intfv(nb_values - 1);
// sum to consecutive values and store the sum in the first half
for (UInt i = 0; i < nb_values_to_sum; ++i) {
intfv(i) = intfv(2*i) + intfv(2*i + 1);
}
nb_values = nb_values_to_sum;
nb_values_to_sum >>= 1;
}
AKANTU_DEBUG_OUT();
return intfv(0);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void IntegratorGauss<kind>::integrateOnQuadraturePoints(const Array<Real> & in_f,
Array<Real> &intf,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
"No jacobians for the type "
<< jacobians.printType(type, ghost_type));
UInt nb_element;
UInt nb_points = GaussIntegrationElement<type>::getNbQuadraturePoints();
const Array<Real> & jac_loc = jacobians(type, ghost_type);
Array<Real>::const_scalar_iterator J_it;
Array<Real>::vector_iterator inte_it;
Array<Real>::const_vector_iterator f_it;
Array<Real> * filtered_J = NULL;
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type, filter_elements);
J_it = filtered_J->begin();
} else {
nb_element = mesh.getNbElement(type,ghost_type);
J_it = jac_loc.begin();
}
intf.resize(nb_element*nb_points);
f_it = in_f.begin(nb_degree_of_freedom);
inte_it = intf.begin(nb_degree_of_freedom);
for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
const Real & J = *J_it;
const Vector<Real> & f = *f_it;
Vector<Real> & inte_f = *inte_it;
inte_f = f;
inte_f *= J;
}
delete filtered_J;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
#define INIT_INTEGRATOR(type) \
computeQuadraturePoints<type>(ghost_type); \
precomputeJacobiansOnQuadraturePoints<type>(nodes, ghost_type); \
checkJacobians<type>(ghost_type); \
multiplyJacobiansByWeights<type>(ghost_type);
template <>
inline void IntegratorGauss<_ek_regular>::initIntegrator(const Array<Real> & nodes,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(INIT_INTEGRATOR);
}
#if defined(AKANTU_COHESIVE_ELEMENT)
template <>
inline void IntegratorGauss<_ek_cohesive>::initIntegrator(const Array<Real> & nodes,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INIT_INTEGRATOR);
}
#endif
#if defined(AKANTU_STRUCTURAL_MECHANICS)
template <>
inline void IntegratorGauss<_ek_structural>::initIntegrator(const Array<Real> & nodes,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(INIT_INTEGRATOR);
}
#endif
#undef INIT_INTEGRATOR
diff --git a/src/fe_engine/interpolation_element.cc b/src/fe_engine/interpolation_element.cc
index ab1b57eba..b4291d578 100644
--- a/src/fe_engine/interpolation_element.cc
+++ b/src/fe_engine/interpolation_element.cc
@@ -1,48 +1,48 @@
/**
* @file interpolation_element.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Fri Jul 04 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Common part of element_classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_class.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Structural elements */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_STRUCTURAL_MECHANICS)
template<> const UInt InterpolationElement<_itp_bernoulli_beam>::nb_shape_functions = 5;
template<> const UInt InterpolationElement<_itp_kirchhoff_shell>::nb_shape_functions = 9;
template<> const UInt InterpolationElement<_itp_bernoulli_beam>::nb_shape_derivatives = 3;
template<> const UInt InterpolationElement<_itp_kirchhoff_shell>::nb_shape_derivatives = 7;
#endif
__END_AKANTU__
diff --git a/src/fe_engine/interpolation_element_tmpl.hh b/src/fe_engine/interpolation_element_tmpl.hh
index 5b6377754..36d398faa 100644
--- a/src/fe_engine/interpolation_element_tmpl.hh
+++ b/src/fe_engine/interpolation_element_tmpl.hh
@@ -1,57 +1,57 @@
/**
* @file interpolation_element_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jun 06 2013
- * @date last modification: Fri Jul 04 2014
+ * @date last modification: Tue Apr 07 2015
*
* @brief interpolation property description
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Regular Elements */
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_point_1, _itk_lagrangian, 1, 0);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_2, _itk_lagrangian, 2, 1);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_3, _itk_lagrangian, 3, 1);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_3, _itk_lagrangian, 3, 2);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_6, _itk_lagrangian, 6, 2);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_4, _itk_lagrangian, 4, 3);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_10, _itk_lagrangian, 10, 3);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_quadrangle_4, _itk_lagrangian, 4, 2);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_quadrangle_8, _itk_lagrangian, 8, 2);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_hexahedron_8, _itk_lagrangian, 8, 3);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_hexahedron_20, _itk_lagrangian, 20, 3);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_6, _itk_lagrangian, 6, 3);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_15, _itk_lagrangian, 15, 3);
/* -------------------------------------------------------------------------- */
/* Structural elements */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_STRUCTURAL_MECHANICS)
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam, _itk_structural, 2, 1);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_kirchhoff_shell, _itk_structural, 3, 2);
#endif
diff --git a/src/fe_engine/shape_cohesive.hh b/src/fe_engine/shape_cohesive.hh
index 59d143eb3..145c29582 100644
--- a/src/fe_engine/shape_cohesive.hh
+++ b/src/fe_engine/shape_cohesive.hh
@@ -1,201 +1,202 @@
/**
* @file shape_cohesive.hh
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri Feb 03 2012
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Tue Feb 15 2011
+ * @date last modification: Thu Oct 22 2015
*
* @brief shape functions for cohesive elements description
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_array.hh"
#include "shape_functions.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SHAPE_COHESIVE_HH__
#define __AKANTU_SHAPE_COHESIVE_HH__
__BEGIN_AKANTU__
struct CohesiveReduceFunctionMean {
inline Real operator()(Real u_plus, Real u_minus) {
return .5*(u_plus + u_minus);
}
};
struct CohesiveReduceFunctionOpening {
inline Real operator()(Real u_plus, Real u_minus) {
return (u_plus - u_minus);
}
};
template<>
class ShapeLagrange<_ek_cohesive> : public ShapeFunctions {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ShapeLagrange(const Mesh & mesh,
const ID & id = "shape_cohesive",
const MemoryID & memory_id = 0);
virtual ~ShapeLagrange() { }
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline void initShapeFunctions(const Array<Real> & nodes,
const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type);
/// extract the nodal values and store them per element
template <ElementType type, class ReduceFunction>
void extractNodalToElementField(const Array<Real> & nodal_f,
Array<Real> & elemental_f,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// pre compute all shapes on the element integration points from natural coordinates
template <ElementType type>
void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
GhostType ghost_type);
/// pre compute all shape derivatives on the element integration points from natural coordinates
template <ElementType type>
void precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
GhostType ghost_type);
/// interpolate nodal values on the integration points
template <ElementType type, class ReduceFunction>
void interpolateOnIntegrationPoints(const Array<Real> &u,
Array<Real> &uq,
UInt nb_degree_of_freedom,
const GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
template <ElementType type>
void interpolateOnIntegrationPoints(const Array<Real> &u,
Array<Real> &uq,
UInt nb_degree_of_freedom,
const GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const {
interpolateOnIntegrationPoints<type, CohesiveReduceFunctionMean>(u, uq, nb_degree_of_freedom, ghost_type, filter_elements);
}
/// compute the gradient of u on the integration points in the natural coordinates
template <ElementType type>
void gradientOnIntegrationPoints(const Array<Real> &u,
Array<Real> &nablauq,
UInt nb_degree_of_freedom,
GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const {
variationOnIntegrationPoints<type, CohesiveReduceFunctionMean>(u, nablauq, nb_degree_of_freedom, ghost_type, filter_elements);
}
/// compute the gradient of u on the integration points
template <ElementType type, class ReduceFunction>
void variationOnIntegrationPoints(const Array<Real> &u,
Array<Real> &nablauq,
UInt nb_degree_of_freedom,
GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// compute the normals to the field u on integration points
template <ElementType type, class ReduceFunction>
void computeNormalsOnIntegrationPoints(const Array<Real> &u,
Array<Real> &normals_u,
GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// multiply a field by shape functions
template <ElementType type>
void fieldTimesShapes(const Array<Real> & field,
Array<Real> & fiedl_times_shapes,
GhostType ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get a the shapes vector
inline const Array<Real> & getShapes(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/// get a the shapes derivatives vector
inline const Array<Real> & getShapesDerivatives(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// shape functions for all elements
ElementTypeMapArray<Real, InterpolationType> shapes;
/// shape functions derivatives for all elements
ElementTypeMapArray<Real, InterpolationType> shapes_derivatives;
};
// __END_AKANTU__
// #include "shape_lagrange.hh"
// __BEGIN_AKANTU__
// template<>
// class ShapeLagrange<_ek_cohesive> : public ShapeCohesive< ShapeLagrange<_ek_regular> > {
// public:
// ShapeLagrange(const Mesh & mesh,
// const ID & id = "shape_cohesive",
// const MemoryID & memory_id = 0) :
// ShapeCohesive< ShapeLagrange<_ek_regular> >(mesh, id, memory_id) { }
// virtual ~ShapeLagrange() { };
// };
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "shape_cohesive_inline_impl.cc"
/// standard output stream operator
template <class ShapeFunction>
inline std::ostream & operator <<(std::ostream & stream, const ShapeCohesive<ShapeFunction> & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_SHAPE_COHESIVE_HH__ */
diff --git a/src/fe_engine/shape_cohesive_inline_impl.cc b/src/fe_engine/shape_cohesive_inline_impl.cc
index 9e48e268e..8eb0bf8e8 100644
--- a/src/fe_engine/shape_cohesive_inline_impl.cc
+++ b/src/fe_engine/shape_cohesive_inline_impl.cc
@@ -1,294 +1,295 @@
/**
* @file shape_cohesive_inline_impl.cc
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Thu Feb 23 2012
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Feb 03 2012
+ * @date last modification: Thu Oct 15 2015
*
* @brief ShapeCohesive inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
inline ShapeLagrange<_ek_cohesive>::ShapeLagrange(const Mesh & mesh,
const ID & id,
const MemoryID & memory_id) :
ShapeFunctions(mesh, id, memory_id),
shapes("shapes_cohesive", id),
shapes_derivatives("shapes_derivatives_cohesive", id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
#define INIT_SHAPE_FUNCTIONS(type) \
setIntegrationPointsByType<type>(integration_points, ghost_type); \
precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type); \
precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
/* -------------------------------------------------------------------------- */
inline void ShapeLagrange<_ek_cohesive>::initShapeFunctions(const Array<Real> & nodes,
const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
}
/* -------------------------------------------------------------------------- */
inline const Array<Real> & ShapeLagrange<_ek_cohesive>::getShapes(const ElementType & el_type,
const GhostType & ghost_type) const {
return shapes(FEEngine::getInterpolationType(el_type), ghost_type);
}
/* -------------------------------------------------------------------------- */
inline const Array<Real> & ShapeLagrange<_ek_cohesive>::getShapesDerivatives(const ElementType & el_type,
const GhostType & ghost_type) const {
return shapes_derivatives(FEEngine::getInterpolationType(el_type), ghost_type);
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
void ShapeLagrange<_ek_cohesive>::precomputeShapesOnIntegrationPoints(__attribute__((unused)) const Array<Real> & nodes,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
Matrix<Real> & natural_coords = integration_points(type, ghost_type);
UInt nb_points = natural_coords.cols();
UInt size_of_shapes = ElementClass<type>::getShapeSize();
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();;
Array<Real> & shapes_tmp = shapes.alloc(nb_element*nb_points,
size_of_shapes,
itp_type,
ghost_type);
Array<Real>::matrix_iterator shapes_it =
shapes_tmp.begin_reinterpret(ElementClass<type>::getNbNodesPerInterpolationElement(), nb_points,
nb_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++shapes_it) {
Matrix<Real> & N = *shapes_it;
ElementClass<type>::computeShapes(natural_coords,
N);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
void ShapeLagrange<_ek_cohesive>::precomputeShapeDerivativesOnIntegrationPoints(__attribute__((unused)) const Array<Real> & nodes,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
UInt spatial_dimension = ElementClass<type>::getNaturalSpaceDimension();
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
Matrix<Real> natural_coords = this->integration_points(type, ghost_type);
UInt nb_points = natural_coords.cols();
// UInt * elem_val = this->mesh->getConnectivity(type, ghost_type).storage();;
UInt nb_element = this->mesh.getConnectivity(type, ghost_type).getSize();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
Array<Real> & shapes_derivatives_tmp =
this->shapes_derivatives.alloc(nb_element*nb_points,
size_of_shapesd,
itp_type,
ghost_type);
Real * shapesd_val = shapes_derivatives_tmp.storage();
for (UInt elem = 0; elem < nb_element; ++elem) {
Tensor3<Real> B(shapesd_val,
spatial_dimension, nb_nodes_per_element, nb_points);
ElementClass<type>::computeDNDS(natural_coords, B);
shapesd_val += size_of_shapesd*nb_points;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type, class ReduceFunction>
void ShapeLagrange<_ek_cohesive>::extractNodalToElementField(const Array<Real> & nodal_f,
Array<Real> & elemental_f,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt nb_nodes_per_itp_element = ElementClass<type>::getNbNodesPerInterpolationElement();
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
UInt nb_degree_of_freedom = nodal_f.getNbComponent();
UInt nb_element = this->mesh.getNbElement(type, ghost_type);
UInt * conn_val = this->mesh.getConnectivity(type, ghost_type).storage();
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
}
elemental_f.resize(nb_element);
Array<Real>::matrix_iterator u_it = elemental_f.begin(nb_degree_of_freedom,
nb_nodes_per_itp_element);
UInt * el_conn;
ReduceFunction reduce_function;
for (UInt el = 0; el < nb_element; ++el, ++u_it) {
Matrix<Real> & u = *u_it;
if(filter_elements != empty_filter) el_conn = conn_val + filter_elements(el) * nb_nodes_per_element;
else el_conn = conn_val + el * nb_nodes_per_element;
// compute the average/difference of the nodal field loaded from cohesive element
for (UInt n = 0; n < nb_nodes_per_itp_element; ++n) {
UInt node_plus = *(el_conn + n);
UInt node_minus = *(el_conn + n + nb_nodes_per_itp_element);
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
Real u_plus = nodal_f(node_plus, d);
Real u_minus = nodal_f(node_minus, d);
u(d, n) = reduce_function(u_plus, u_minus);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type, class ReduceFunction>
void ShapeLagrange<_ek_cohesive>::interpolateOnIntegrationPoints(const Array<Real> &in_u,
Array<Real> &out_uq,
UInt nb_degree_of_freedom,
GhostType ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
AKANTU_DEBUG_ASSERT(this->shapes.exists(itp_type, ghost_type),
"No shapes for the type "
<< this->shapes.printType(itp_type, ghost_type));
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
this->extractNodalToElementField<type, ReduceFunction>(in_u, u_el, ghost_type, filter_elements);
this->template interpolateElementalFieldOnIntegrationPoints<type>(u_el, out_uq, ghost_type,
shapes(itp_type, ghost_type),
filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type, class ReduceFunction>
void ShapeLagrange<_ek_cohesive>::variationOnIntegrationPoints(const Array<Real> &in_u,
Array<Real> &nablauq,
UInt nb_degree_of_freedom,
GhostType ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
AKANTU_DEBUG_ASSERT(this->shapes_derivatives.exists(itp_type, ghost_type),
"No shapes for the type "
<< this->shapes_derivatives.printType(itp_type, ghost_type));
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
this->extractNodalToElementField<type, ReduceFunction>(in_u, u_el, ghost_type, filter_elements);
this->template gradientElementalFieldOnIntegrationPoints<type>(u_el, nablauq, ghost_type,
shapes_derivatives(itp_type, ghost_type),
filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type, class ReduceFunction>
void ShapeLagrange<_ek_cohesive>::computeNormalsOnIntegrationPoints(const Array<Real> &u,
Array<Real> &normals_u,
GhostType ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt nb_element = this->mesh.getNbElement(type, ghost_type);
UInt nb_points = this->integration_points(type, ghost_type).cols();
UInt spatial_dimension = this->mesh.getSpatialDimension();
if(filter_elements != empty_filter)
nb_element = filter_elements.getSize();
normals_u.resize(nb_points * nb_element);
Array<Real> tangents_u(nb_element * nb_points,
(spatial_dimension * (spatial_dimension -1)));
this->template variationOnIntegrationPoints<type, ReduceFunction>(u,
tangents_u,
spatial_dimension,
ghost_type,
filter_elements);
Array<Real>::vector_iterator normal = normals_u.begin(spatial_dimension);
Array<Real>::vector_iterator normal_end = normals_u.end(spatial_dimension);
Real * tangent = tangents_u.storage();
if(spatial_dimension == 3)
for (; normal != normal_end; ++normal) {
Math::vectorProduct3(tangent, tangent+spatial_dimension, normal->storage());
(*normal) /= normal->norm();
tangent += spatial_dimension * 2;
}
else if (spatial_dimension == 2)
for (; normal != normal_end; ++normal) {
Vector<Real> a1(tangent, spatial_dimension);
(*normal)(0) = -a1(1);
(*normal)(1) = a1(0);
(*normal) /= normal->norm();
tangent += spatial_dimension;
}
AKANTU_DEBUG_OUT();
}
diff --git a/src/fe_engine/shape_functions.hh b/src/fe_engine/shape_functions.hh
index 3099caf38..b8d935e57 100644
--- a/src/fe_engine/shape_functions.hh
+++ b/src/fe_engine/shape_functions.hh
@@ -1,188 +1,190 @@
/**
* @file shape_functions.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Feb 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 22 2015
*
* @brief shape function class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_memory.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SHAPE_FUNCTIONS_HH__
#define __AKANTU_SHAPE_FUNCTIONS_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class ShapeFunctions : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ShapeFunctions(const Mesh & mesh,
const ID & id = "shape",
const MemoryID & memory_id = 0) :
Memory(id, memory_id), mesh(mesh) {
};
virtual ~ShapeFunctions(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Shapes [" << std::endl;
integration_points.printself(stream, indent + 1);
stream << space << "]" << std::endl;
};
/// set the integration points for a given element
template <ElementType type>
void setIntegrationPointsByType(const Matrix<Real> & integration_points,
const GhostType & ghost_type);
/// Build pre-computed matrices for interpolation of field form integration points at other given positions (interpolation_points)
inline void initElementalFieldInterpolationFromIntegrationPoints(const ElementTypeMapArray<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
const ElementTypeMapArray<Real> & quadrature_points_coordinates,
const ElementTypeMapArray<UInt> * element_filter) const;
/// Interpolate field at given position from given values of this field at integration points (field)
/// using matrices precomputed with initElementalFieldInterplationFromIntegrationPoints
inline void interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const ElementTypeMapArray<UInt> * element_filter) const;
protected:
/// interpolate nodal values stored by element on the integration points
template <ElementType type>
void interpolateElementalFieldOnIntegrationPoints(const Array<Real> &u_el,
Array<Real> &uq,
GhostType ghost_type,
const Array<Real> & shapes,
const Array<UInt> & filter_elements) const;
/// gradient of nodal values stored by element on the control points
template <ElementType type>
void gradientElementalFieldOnIntegrationPoints(const Array<Real> &u_el,
Array<Real> &out_nablauq,
GhostType ghost_type,
const Array<Real> & shapes_derivatives,
const Array<UInt> & filter_elements) const;
/// By element versions of non-templated eponym methods
template <ElementType type>
inline void interpolateElementalFieldFromIntegrationPoints(const Array<Real> & field,
const Array<Real> & interpolation_points_coordinates_matrices,
const Array<Real> & quad_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const Array<UInt> & element_filter) const;
/// Interpolate field at given position from given values of this field at integration points (field)
/// using matrices precomputed with initElementalFieldInterplationFromIntegrationPoints
template <ElementType type>
inline void initElementalFieldInterpolationFromIntegrationPoints(const Array<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
const Array<Real> & quadrature_points_coordinates,
GhostType & ghost_type,
const Array<UInt> & element_filter) const;
/// build matrix for the interpolation of field form integration points
template <ElementType type>
inline void buildElementalFieldInterpolationMatrix(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order =
ElementClassProperty<type>::minimal_integration_order) const;
/// build the so called interpolation matrix (first collumn is 1, then the other collumns are the traansposed coordinates)
inline void buildInterpolationMatrix(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the size of the shapes returned by the element class
static inline UInt getShapeSize(const ElementType & type);
/// get the size of the shapes derivatives returned by the element class
static inline UInt getShapeDerivativesSize(const ElementType & type);
inline const Matrix<Real> & getIntegrationPoints(const ElementType & type,
const GhostType & ghost_type) const {
return integration_points(type, ghost_type);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// associated mesh
const Mesh & mesh;
/// shape functions for all elements
ElementTypeMap< Matrix<Real> > integration_points;
};
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "shape_functions_inline_impl.cc"
#endif
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const ShapeFunctions & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_SHAPE_FUNCTIONS_HH__ */
diff --git a/src/fe_engine/shape_functions_inline_impl.cc b/src/fe_engine/shape_functions_inline_impl.cc
index 419c059d1..1964c10e2 100644
--- a/src/fe_engine/shape_functions_inline_impl.cc
+++ b/src/fe_engine/shape_functions_inline_impl.cc
@@ -1,584 +1,585 @@
/**
* @file shape_functions_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri Jul 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Wed Oct 27 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief ShapeFunctions inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include "fe_engine.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline UInt ShapeFunctions::getShapeSize(const ElementType & type) {
AKANTU_DEBUG_IN();
UInt shape_size = 0;
#define GET_SHAPE_SIZE(type) \
shape_size = ElementClass<type>::getShapeSize()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_SIZE);// ,
#undef GET_SHAPE_SIZE
AKANTU_DEBUG_OUT();
return shape_size;
}
/* -------------------------------------------------------------------------- */
inline UInt ShapeFunctions::getShapeDerivativesSize(const ElementType & type) {
AKANTU_DEBUG_IN();
UInt shape_derivatives_size = 0;
#define GET_SHAPE_DERIVATIVES_SIZE(type) \
shape_derivatives_size = ElementClass<type>::getShapeDerivativesSize()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_DERIVATIVES_SIZE);// ,
#undef GET_SHAPE_DERIVATIVES_SIZE
AKANTU_DEBUG_OUT();
return shape_derivatives_size;
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
void ShapeFunctions::setIntegrationPointsByType(const Matrix<Real> & points,
const GhostType & ghost_type) {
integration_points(type, ghost_type).shallowCopy(points);
}
/* -------------------------------------------------------------------------- */
inline void ShapeFunctions::initElementalFieldInterpolationFromIntegrationPoints(const ElementTypeMapArray<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
const ElementTypeMapArray<Real> & quadrature_points_coordinates,
const ElementTypeMapArray<UInt> * element_filter) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = this->mesh.getSpatialDimension();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Mesh::type_iterator it, last;
if(element_filter) {
it = element_filter->firstType(spatial_dimension, ghost_type);
last = element_filter->lastType(spatial_dimension, ghost_type);
}
else {
it = mesh.firstType(spatial_dimension, ghost_type);
last = mesh.lastType(spatial_dimension, ghost_type);
}
for (; it != last; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type, ghost_type);
if (nb_element == 0) continue;
const Array<UInt> * elem_filter;
if(element_filter) elem_filter = &((*element_filter)(type, ghost_type));
else elem_filter = &(empty_filter);
#define AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS(type) \
initElementalFieldInterpolationFromIntegrationPoints<type>(interpolation_points_coordinates(type, ghost_type), \
interpolation_points_coordinates_matrices, \
quad_points_coordinates_inv_matrices, \
quadrature_points_coordinates(type, ghost_type), \
ghost_type, \
*elem_filter) \
AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS);
#undef AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
inline void ShapeFunctions::initElementalFieldInterpolationFromIntegrationPoints(const Array<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
const Array<Real> & quadrature_points_coordinates,
GhostType & ghost_type,
const Array<UInt> & element_filter) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = this->mesh.getSpatialDimension();
UInt nb_element = this->mesh.getNbElement(type, ghost_type);
UInt nb_element_filter;
if(element_filter == empty_filter)
nb_element_filter = nb_element;
else nb_element_filter = element_filter.getSize();
UInt nb_quad_per_element = GaussIntegrationElement<type>::getNbQuadraturePoints();
UInt nb_interpolation_points_per_elem = interpolation_points_coordinates.getSize() / nb_element;
AKANTU_DEBUG_ASSERT(interpolation_points_coordinates.getSize() % nb_element == 0,
"Number of interpolation points should be a multiple of total number of elements");
if(!quad_points_coordinates_inv_matrices.exists(type, ghost_type))
quad_points_coordinates_inv_matrices.alloc(nb_element_filter,
nb_quad_per_element*nb_quad_per_element,
type, ghost_type);
else
quad_points_coordinates_inv_matrices(type, ghost_type).resize(nb_element_filter);
if(!interpolation_points_coordinates_matrices.exists(type, ghost_type))
interpolation_points_coordinates_matrices.alloc(nb_element_filter,
nb_interpolation_points_per_elem * nb_quad_per_element,
type, ghost_type);
else
interpolation_points_coordinates_matrices(type, ghost_type).resize(nb_element_filter);
Array<Real> & quad_inv_mat = quad_points_coordinates_inv_matrices(type, ghost_type);
Array<Real> & interp_points_mat = interpolation_points_coordinates_matrices(type, ghost_type);
Matrix<Real> quad_coord_matrix(nb_quad_per_element, nb_quad_per_element);
Array<Real>::const_matrix_iterator quad_coords_it =
quadrature_points_coordinates.begin_reinterpret(spatial_dimension,
nb_quad_per_element,
nb_element_filter);
Array<Real>::const_matrix_iterator points_coords_begin =
interpolation_points_coordinates.begin_reinterpret(spatial_dimension,
nb_interpolation_points_per_elem,
nb_element);
Array<Real>::matrix_iterator inv_quad_coord_it =
quad_inv_mat.begin(nb_quad_per_element, nb_quad_per_element);
Array<Real>::matrix_iterator int_points_mat_it =
interp_points_mat.begin(nb_interpolation_points_per_elem, nb_quad_per_element);
/// loop over the elements of the current material and element type
for (UInt el = 0; el < nb_element_filter; ++el, ++inv_quad_coord_it,
++int_points_mat_it, ++quad_coords_it) {
/// matrix containing the quadrature points coordinates
const Matrix<Real> & quad_coords = *quad_coords_it;
/// matrix to store the matrix inversion result
Matrix<Real> & inv_quad_coord_matrix = *inv_quad_coord_it;
/// insert the quad coordinates in a matrix compatible with the interpolation
buildElementalFieldInterpolationMatrix<type>(quad_coords,
quad_coord_matrix);
/// invert the interpolation matrix
inv_quad_coord_matrix.inverse(quad_coord_matrix);
/// matrix containing the interpolation points coordinates
const Matrix<Real> & points_coords = points_coords_begin[element_filter(el)];
/// matrix to store the interpolation points coordinates
/// compatible with these functions
Matrix<Real> & inv_points_coord_matrix = *int_points_mat_it;
/// insert the quad coordinates in a matrix compatible with the interpolation
buildElementalFieldInterpolationMatrix<type>(points_coords,
inv_points_coord_matrix);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void ShapeFunctions::buildInterpolationMatrix(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
switch (integration_order) {
case 1:{
for (UInt i = 0; i < coordinates.cols(); ++i)
coordMatrix(i, 0) = 1;
break;
}
case 2:{
UInt nb_quadrature_points = coordMatrix.cols();
for (UInt i = 0; i < coordinates.cols(); ++i) {
coordMatrix(i, 0) = 1;
for (UInt j = 1; j < nb_quadrature_points; ++j)
coordMatrix(i, j) = coordinates(j-1, i);
}
break;
}
default:{
AKANTU_DEBUG_TO_IMPLEMENT();
break;
}
}
}
/* -------------------------------------------------------------------------- */
template<ElementType type>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix(__attribute__((unused)) const Matrix<Real> & coordinates,
__attribute__((unused)) Matrix<Real> & coordMatrix,
__attribute__((unused)) UInt integration_order) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template<>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_2>(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template<>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_3>(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template<>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_3>(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template<>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_6>(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template<>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_4>(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template<>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_10>(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/**
* @todo Write a more efficient interpolation for quadrangles by
* dropping unnecessary quadrature points
*
*/
/* -------------------------------------------------------------------------- */
template<>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_4>(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
if(integration_order!=ElementClassProperty<_quadrangle_4>::minimal_integration_order){
AKANTU_DEBUG_TO_IMPLEMENT();
} else {
for (UInt i = 0; i < coordinates.cols(); ++i) {
Real x = coordinates(0, i);
Real y = coordinates(1, i);
coordMatrix(i, 0) = 1;
coordMatrix(i, 1) = x;
coordMatrix(i, 2) = y;
coordMatrix(i, 3) = x * y;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_8>(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
if(integration_order!=ElementClassProperty<_quadrangle_8>::minimal_integration_order){
AKANTU_DEBUG_TO_IMPLEMENT();
} else {
for (UInt i = 0; i < coordinates.cols(); ++i) {
UInt j = 0;
Real x = coordinates(0, i);
Real y = coordinates(1, i);
for (UInt e = 0; e <= 2; ++e) {
for (UInt n = 0; n <= 2; ++n) {
coordMatrix(i, j) = std::pow(x, e) * std::pow(y, n);
++j;
}
}
}
}
}
/* -------------------------------------------------------------------------- */
void ShapeFunctions::interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const ElementTypeMapArray<UInt> * element_filter) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = this->mesh.getSpatialDimension();
Mesh::type_iterator it, last;
if(element_filter) {
it = element_filter->firstType(spatial_dimension, ghost_type);
last = element_filter->lastType(spatial_dimension, ghost_type);
}
else {
it = mesh.firstType(spatial_dimension, ghost_type);
last = mesh.lastType(spatial_dimension, ghost_type);
}
for (; it != last; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type, ghost_type);
if (nb_element == 0) continue;
const Array<UInt> * elem_filter;
if(element_filter) elem_filter = &((*element_filter)(type, ghost_type));
else elem_filter = &(empty_filter);
#define AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS(type) \
interpolateElementalFieldFromIntegrationPoints<type>(field(type, ghost_type), \
interpolation_points_coordinates_matrices(type, ghost_type), \
quad_points_coordinates_inv_matrices(type, ghost_type), \
result, \
ghost_type, \
*elem_filter) \
AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS);
#undef AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
inline void ShapeFunctions::interpolateElementalFieldFromIntegrationPoints(const Array<Real> & field,
const Array<Real> & interpolation_points_coordinates_matrices,
const Array<Real> & quad_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result,
const GhostType ghost_type,
const Array<UInt> & element_filter) const {
AKANTU_DEBUG_IN();
UInt nb_element = this->mesh.getNbElement(type, ghost_type);
UInt nb_quad_per_element = GaussIntegrationElement<type>::getNbQuadraturePoints();
UInt nb_interpolation_points_per_elem
= interpolation_points_coordinates_matrices.getNbComponent() / nb_quad_per_element;
if(!result.exists(type, ghost_type))
result.alloc(nb_element*nb_interpolation_points_per_elem,
field.getNbComponent(),
type, ghost_type);
if(element_filter != empty_filter)
nb_element = element_filter.getSize();
Matrix<Real> coefficients(nb_quad_per_element, field.getNbComponent());
Array<Real> & result_vec = result(type, ghost_type);
Array<Real>::const_matrix_iterator field_it
= field.begin_reinterpret(field.getNbComponent(),
nb_quad_per_element,
nb_element);
Array<Real>::const_matrix_iterator interpolation_points_coordinates_it =
interpolation_points_coordinates_matrices.begin(nb_interpolation_points_per_elem, nb_quad_per_element);
Array<Real>::matrix_iterator result_begin
= result_vec.begin_reinterpret(field.getNbComponent(),
nb_interpolation_points_per_elem,
result_vec.getSize() / nb_interpolation_points_per_elem);
Array<Real>::const_matrix_iterator inv_quad_coord_it =
quad_points_coordinates_inv_matrices.begin(nb_quad_per_element, nb_quad_per_element);
/// loop over the elements of the current filter and element type
for (UInt el = 0; el < nb_element;
++el, ++field_it, ++inv_quad_coord_it, ++interpolation_points_coordinates_it) {
/**
* matrix containing the inversion of the quadrature points'
* coordinates
*/
const Matrix<Real> & inv_quad_coord_matrix = *inv_quad_coord_it;
/**
* multiply it by the field values over quadrature points to get
* the interpolation coefficients
*/
coefficients.mul<false, true>(inv_quad_coord_matrix, *field_it);
/// matrix containing the points' coordinates
const Matrix<Real> & coord = *interpolation_points_coordinates_it;
/// multiply the coordinates matrix by the coefficients matrix and store the result
Matrix<Real> res(result_begin[element_filter(el)]);
res.mul<true, true>(coefficients, coord);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
inline void ShapeFunctions::interpolateElementalFieldOnIntegrationPoints(const Array<Real> &u_el,
Array<Real> &uq,
GhostType ghost_type,
const Array<Real> & shapes,
const Array<UInt> & filter_elements) const {
UInt nb_element;
UInt nb_points = integration_points(type, ghost_type).cols();
UInt nb_nodes_per_element = ElementClass<type>::getShapeSize();
UInt nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element;
Array<Real>::const_matrix_iterator N_it;
Array<Real>::const_matrix_iterator u_it;
Array<Real>::matrix_iterator inter_u_it;
Array<Real> * filtered_N = NULL;
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
filtered_N = new Array<Real>(0, shapes.getNbComponent());
FEEngine::filterElementalData(mesh, shapes, *filtered_N, type, ghost_type, filter_elements);
N_it = filtered_N->begin_reinterpret(nb_nodes_per_element, nb_points, nb_element);
} else {
nb_element = mesh.getNbElement(type,ghost_type);
N_it = shapes.begin_reinterpret(nb_nodes_per_element, nb_points, nb_element);
}
uq.resize(nb_element*nb_points);
u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element);
inter_u_it = uq.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element);
for (UInt el = 0; el < nb_element; ++el, ++N_it, ++u_it, ++inter_u_it) {
const Matrix<Real> & u = *u_it;
const Matrix<Real> & N = *N_it;
Matrix<Real> & inter_u = *inter_u_it;
inter_u.mul<false, false>(u, N);
}
delete filtered_N;
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
void ShapeFunctions::gradientElementalFieldOnIntegrationPoints(const Array<Real> &u_el,
Array<Real> &out_nablauq,
GhostType ghost_type,
const Array<Real> & shapes_derivatives,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
UInt nb_points = integration_points(type, ghost_type).cols();
UInt element_dimension = ElementClass<type>::getNaturalSpaceDimension();
UInt nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element;
Array<Real>::const_matrix_iterator B_it;
Array<Real>::const_matrix_iterator u_it;
Array<Real>::matrix_iterator nabla_u_it;
UInt nb_element;
Array<Real> * filtered_B = NULL;
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
filtered_B = new Array<Real>(0, shapes_derivatives.getNbComponent());
FEEngine::filterElementalData(mesh, shapes_derivatives, *filtered_B, type, ghost_type, filter_elements);
B_it = filtered_B->begin(element_dimension, nb_nodes_per_element);
} else {
B_it = shapes_derivatives.begin(element_dimension, nb_nodes_per_element);
nb_element = mesh.getNbElement(type, ghost_type);
}
out_nablauq.resize(nb_element*nb_points);
u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element);
nabla_u_it = out_nablauq.begin(nb_degree_of_freedom, element_dimension);
for (UInt el = 0; el < nb_element; ++el, ++u_it) {
const Matrix<Real> & u = *u_it;
for (UInt q = 0; q < nb_points; ++q, ++B_it, ++nabla_u_it) {
const Matrix<Real> & B = *B_it;
Matrix<Real> & nabla_u = *nabla_u_it;
nabla_u.mul<false, true>(u, B);
}
}
delete filtered_B;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
diff --git a/src/fe_engine/shape_lagrange.cc b/src/fe_engine/shape_lagrange.cc
index d50bf2c4f..1149c5cf1 100644
--- a/src/fe_engine/shape_lagrange.cc
+++ b/src/fe_engine/shape_lagrange.cc
@@ -1,31 +1,32 @@
/**
* @file shape_lagrange.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Feb 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief lagrangian shape functions class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
diff --git a/src/fe_engine/shape_lagrange.hh b/src/fe_engine/shape_lagrange.hh
index ecb41153c..41061d22b 100644
--- a/src/fe_engine/shape_lagrange.hh
+++ b/src/fe_engine/shape_lagrange.hh
@@ -1,175 +1,176 @@
/**
* @file shape_lagrange.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Feb 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Thu Nov 05 2015
*
* @brief lagrangian shape functions class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
#ifndef __AKANTU_SHAPE_LAGRANGE_HH__
#define __AKANTU_SHAPE_LAGRANGE_HH__
#include "shape_functions.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<class Shape>
class ShapeCohesive;
class ShapeIGFEM;
template <ElementKind kind>
class ShapeLagrange : public ShapeFunctions {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ShapeLagrange(const Mesh & mesh,
const ID & id = "shape_lagrange",
const MemoryID & memory_id = 0);
virtual ~ShapeLagrange(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialization function for structural elements not yet implemented
inline void initShapeFunctions(const Array<Real> & nodes,
const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type);
/// pre compute all shapes on the element integration points from natural coordinates
template<ElementType type>
void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
GhostType ghost_type);
/// pre compute all shape derivatives on the element integration points from natural coordinates
template <ElementType type>
void precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
GhostType ghost_type);
/// interpolate nodal values on the integration points
template <ElementType type>
void interpolateOnIntegrationPoints(const Array<Real> &u,
Array<Real> &uq,
UInt nb_degree_of_freedom,
GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// interpolate on physical point
template <ElementType type>
void interpolate(const Vector <Real> & real_coords,
UInt elem,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated,
const GhostType & ghost_type) const;
/// compute the gradient of u on the integration points
template <ElementType type>
void gradientOnIntegrationPoints(const Array<Real> &u,
Array<Real> &nablauq,
UInt nb_degree_of_freedom,
GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// multiply a field by shape functions @f$ fts_{ij} = f_i * \varphi_j @f$
template <ElementType type>
void fieldTimesShapes(const Array<Real> & field,
Array<Real> & field_times_shapes,
GhostType ghost_type) const;
/// find natural coords from real coords provided an element
template <ElementType type>
void inverseMap(const Vector<Real> & real_coords,
UInt element,
Vector<Real> & natural_coords,
const GhostType & ghost_type = _not_ghost) const;
/// return true if the coordinates provided are inside the element, false otherwise
template <ElementType type>
bool contains(const Vector<Real> & real_coords,
UInt elem,
const GhostType & ghost_type) const;
/// compute the shape on a provided point
template <ElementType type>
void computeShapes(const Vector<Real> & real_coords,
UInt elem,
Vector<Real> & shapes,
const GhostType & ghost_type) const;
/// compute the shape derivatives on a provided point
template <ElementType type>
void computeShapeDerivatives(const Matrix<Real> & real_coords,
UInt elem,
Tensor3<Real> & shapes,
const GhostType & ghost_type) const;
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
/// compute the shape derivatives on integration points for a given element
template <ElementType type>
inline void computeShapeDerivativesOnCPointsByElement(const Matrix<Real> & node_coords,
const Matrix<Real> & natural_coords,
Tensor3<Real> & shapesd) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get a the shapes vector
inline const Array<Real> & getShapes(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/// get a the shapes derivatives vector
inline const Array<Real> & getShapesDerivatives(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// shape functions for all elements
ElementTypeMapArray<Real, InterpolationType> shapes;
/// shape functions derivatives for all elements
ElementTypeMapArray<Real, InterpolationType> shapes_derivatives;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "shape_lagrange_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_SHAPE_LAGRANGE_HH__ */
diff --git a/src/fe_engine/shape_lagrange_inline_impl.cc b/src/fe_engine/shape_lagrange_inline_impl.cc
index d07ee222d..6229d0552 100644
--- a/src/fe_engine/shape_lagrange_inline_impl.cc
+++ b/src/fe_engine/shape_lagrange_inline_impl.cc
@@ -1,410 +1,411 @@
/**
* @file shape_lagrange_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Feb 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Wed Oct 27 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief ShapeLagrange inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
__END_AKANTU__
#include "fe_engine.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
inline const Array<Real> & ShapeLagrange<kind>::getShapes(const ElementType & el_type,
const GhostType & ghost_type) const {
return shapes(FEEngine::getInterpolationType(el_type), ghost_type);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
inline const Array<Real> & ShapeLagrange<kind>::getShapesDerivatives(const ElementType & el_type,
const GhostType & ghost_type) const {
return shapes_derivatives(FEEngine::getInterpolationType(el_type), ghost_type);
}
/* -------------------------------------------------------------------------- */
#define INIT_SHAPE_FUNCTIONS(type) \
setIntegrationPointsByType<type>(integration_points, ghost_type); \
precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type); \
if (ElementClass<type>::getNaturalSpaceDimension() == \
mesh.getSpatialDimension() || kind != _ek_regular) \
precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
template <ElementKind kind>
inline void
ShapeLagrange<kind>::initShapeFunctions(const Array<Real> & nodes,
const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
}
#if defined(AKANTU_STRUCTURAL_MECHANICS)
/* -------------------------------------------------------------------------- */
template <>
inline void
ShapeLagrange<_ek_structural>::initShapeFunctions(__attribute__((unused)) const Array<Real> & nodes,
__attribute__((unused)) const Matrix<Real> & integration_points,
__attribute__((unused)) const ElementType & type,
__attribute__((unused)) const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
#endif
#undef INIT_SHAPE_FUNCTIONS
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
inline void ShapeLagrange<kind>::
computeShapeDerivativesOnCPointsByElement(const Matrix<Real> & node_coords,
const Matrix<Real> & natural_coords,
Tensor3<Real> & shapesd) const {
AKANTU_DEBUG_IN();
// compute dnds
Tensor3<Real> dnds(node_coords.rows(), node_coords.cols(), natural_coords.cols());
ElementClass<type>::computeDNDS(natural_coords, dnds);
// compute dxds
Tensor3<Real> J(node_coords.rows(), natural_coords.rows(), natural_coords.cols());
ElementClass<type>::computeJMat(dnds, node_coords, J);
// compute shape derivatives
ElementClass<type>::computeShapeDerivatives(J, dnds, shapesd);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::inverseMap(const Vector<Real> & real_coords,
UInt elem,
Vector<Real> & natural_coords,
const GhostType & ghost_type) const{
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
mesh.extractNodalValuesFromElement(mesh.getNodes(),
nodes_coord.storage(),
elem_val + elem*nb_nodes_per_element,
nb_nodes_per_element,
spatial_dimension);
ElementClass<type>::inverseMap(real_coords,
nodes_coord,
natural_coords);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
bool ShapeLagrange<kind>::contains(const Vector<Real> & real_coords,
UInt elem,
const GhostType & ghost_type) const{
UInt spatial_dimension = mesh.getSpatialDimension();
Vector<Real> natural_coords(spatial_dimension);
inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
return ElementClass<type>::contains(natural_coords);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::interpolate(const Vector <Real> & real_coords,
UInt elem,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated,
const GhostType & ghost_type) const {
UInt nb_shapes = ElementClass<type>::getShapeSize();
Vector<Real> shapes(nb_shapes);
computeShapes<type>(real_coords, elem, shapes, ghost_type);
ElementClass<type>::interpolate(nodal_values, shapes, interpolated);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::computeShapes(const Vector<Real> & real_coords,
UInt elem,
Vector<Real> & shapes,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
Vector<Real> natural_coords(spatial_dimension);
inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
ElementClass<type>::computeShapes(natural_coords, shapes);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::computeShapeDerivatives(const Matrix<Real> & real_coords,
UInt elem,
Tensor3<Real> & shapesd,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_points = real_coords.cols();
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == shapesd.size(0) && nb_nodes_per_element == shapesd.size(1),
"Shape size doesn't match");
AKANTU_DEBUG_ASSERT(nb_points == shapesd.size(2),
"Number of points doesn't match shapes size");
Matrix<Real> natural_coords(spatial_dimension, nb_points);
// Creates the matrix of natural coordinates
for (UInt i = 0 ; i < nb_points ; i++) {
Vector<Real> real_point = real_coords(i);
Vector<Real> natural_point = natural_coords(i);
inverseMap<type>(real_point, elem, natural_point, ghost_type);
}
UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
mesh.extractNodalValuesFromElement(mesh.getNodes(),
nodes_coord.storage(),
elem_val + elem*nb_nodes_per_element,
nb_nodes_per_element,
spatial_dimension);
computeShapeDerivativesOnCPointsByElement<type>(nodes_coord, natural_coords, shapesd);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
ShapeLagrange<kind>::ShapeLagrange(const Mesh & mesh,
const ID & id,
const MemoryID & memory_id) :
ShapeFunctions(mesh, id, memory_id),
shapes("shapes_generic", id),
shapes_derivatives("shapes_derivatives_generic", id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::precomputeShapesOnIntegrationPoints(__attribute__((unused)) const Array<Real> & nodes,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
Matrix<Real> & natural_coords = integration_points(type, ghost_type);
UInt nb_points = natural_coords.cols();
UInt size_of_shapes = ElementClass<type>::getShapeSize();
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();;
Array<Real> & shapes_tmp = shapes.alloc(nb_element*nb_points,
size_of_shapes,
itp_type,
ghost_type);
Array<Real>::matrix_iterator shapes_it =
shapes_tmp.begin_reinterpret(ElementClass<type>::getNbNodesPerInterpolationElement(), nb_points,
nb_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++shapes_it) {
Matrix<Real> & N = *shapes_it;
ElementClass<type>::computeShapes(natural_coords,
N);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes, GhostType ghost_type) {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
// Real * coord = mesh.getNodes().storage();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
Matrix<Real> & natural_coords = integration_points(type, ghost_type);
UInt nb_points = natural_coords.cols();
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
Array<Real> & shapes_derivatives_tmp = shapes_derivatives.alloc(nb_element*nb_points,
size_of_shapesd,
itp_type,
ghost_type);
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el,
type, ghost_type);
Real * shapesd_val = shapes_derivatives_tmp.storage();
Array<Real>::matrix_iterator x_it = x_el.begin(spatial_dimension,
nb_nodes_per_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
Matrix<Real> & X = *x_it;
Tensor3<Real> B(shapesd_val,
spatial_dimension, nb_nodes_per_element, nb_points);
computeShapeDerivativesOnCPointsByElement<type>(X,
natural_coords,
B);
shapesd_val += size_of_shapesd*nb_points;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::interpolateOnIntegrationPoints(const Array<Real> &in_u,
Array<Real> &out_uq,
UInt nb_degree_of_freedom,
GhostType ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
AKANTU_DEBUG_ASSERT(shapes.exists(itp_type, ghost_type),
"No shapes for the type "
<< shapes.printType(itp_type, ghost_type));
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type, filter_elements);
this->interpolateElementalFieldOnIntegrationPoints<type>(u_el, out_uq, ghost_type,
shapes(itp_type, ghost_type),
filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::gradientOnIntegrationPoints(const Array<Real> &in_u,
Array<Real> &out_nablauq,
UInt nb_degree_of_freedom,
GhostType ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
AKANTU_DEBUG_ASSERT(shapes_derivatives.exists(itp_type, ghost_type),
"No shapes derivatives for the type "
<< shapes_derivatives.printType(itp_type, ghost_type));
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type, filter_elements);
this->gradientElementalFieldOnIntegrationPoints<type>(u_el, out_nablauq, ghost_type,
shapes_derivatives(itp_type, ghost_type),
filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::fieldTimesShapes(const Array<Real> & field,
Array<Real> & field_times_shapes,
GhostType ghost_type) const {
AKANTU_DEBUG_IN();
field_times_shapes.resize(field.getSize());
UInt size_of_shapes = ElementClass<type>::getShapeSize();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
UInt nb_degree_of_freedom = field.getNbComponent();
const Array<Real> & shape = shapes(itp_type, ghost_type);
Array<Real>::const_matrix_iterator field_it = field.begin(nb_degree_of_freedom, 1);
Array<Real>::const_matrix_iterator shapes_it = shape.begin(1, size_of_shapes);
Array<Real>::matrix_iterator it = field_times_shapes.begin(nb_degree_of_freedom, size_of_shapes);
Array<Real>::matrix_iterator end = field_times_shapes.end (nb_degree_of_freedom, size_of_shapes);
for (; it != end; ++it, ++field_it, ++shapes_it) {
it->mul<false, false>(*field_it, *shapes_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
void ShapeLagrange<kind>::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Shapes Lagrange [" << std::endl;
ShapeFunctions::printself(stream, indent + 1);
shapes.printself(stream, indent + 1);
shapes_derivatives.printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
diff --git a/src/fe_engine/shape_linked.cc b/src/fe_engine/shape_linked.cc
index 78702e4da..eb5f8eaa1 100644
--- a/src/fe_engine/shape_linked.cc
+++ b/src/fe_engine/shape_linked.cc
@@ -1,81 +1,82 @@
/**
* @file shape_linked.cc
*
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief ShapeLinked implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_memory.hh"
#include "mesh.hh"
#include "shape_linked.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
#if defined(AKANTU_STRUCTURAL_MECHANICS)
/* -------------------------------------------------------------------------- */
template <>
ShapeLinked<_ek_structural>::ShapeLinked(Mesh & mesh, const ID & id, const MemoryID & memory_id) :
ShapeFunctions(mesh, id, memory_id)
{
}
/* -------------------------------------------------------------------------- */
template <>
ShapeLinked<_ek_structural>::~ShapeLinked() {
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
// delete all the shapes id
ElementTypeMapMultiReal::type_iterator s_type_it =
shapes.firstType(_all_dimensions, ghost_type, _ek_structural);
ElementTypeMapMultiReal::type_iterator s_type_end =
shapes.lastType (_all_dimensions, ghost_type, _ek_structural);
for(; s_type_it != s_type_end; ++s_type_it) {
delete [] shapes(*s_type_it, ghost_type);
}
// delete all the shapes derivatives id
ElementTypeMapMultiReal::type_iterator sd_type_it =
shapes_derivatives.firstType(_all_dimensions, ghost_type, _ek_structural);
ElementTypeMapMultiReal::type_iterator sd_type_end =
shapes_derivatives.lastType (_all_dimensions, ghost_type, _ek_structural);
for(; sd_type_it != sd_type_end; ++sd_type_it) {
delete [] shapes_derivatives(*sd_type_it, ghost_type);
}
}
}
#endif
__END_AKANTU__
diff --git a/src/fe_engine/shape_linked.hh b/src/fe_engine/shape_linked.hh
index 6137fae49..48dc59731 100644
--- a/src/fe_engine/shape_linked.hh
+++ b/src/fe_engine/shape_linked.hh
@@ -1,160 +1,161 @@
/**
* @file shape_linked.hh
*
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Jul 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Tue Feb 15 2011
+ * @date last modification: Thu Oct 22 2015
*
* @brief shape class for element with different set of shapes functions
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "shape_functions.hh"
#ifndef __AKANTU_SHAPE_LINKED_HH__
#define __AKANTU_SHAPE_LINKED_HH__
__BEGIN_AKANTU__
template <ElementKind kind>
class ShapeLinked : public ShapeFunctions {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef ElementTypeMap<Array<Real> **> ElementTypeMapMultiReal;
ShapeLinked(Mesh & mesh, const ID & id = "shape_linked", const MemoryID & memory_id = 0);
virtual ~ShapeLinked();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialization function for structural elements
inline void initShapeFunctions(const Array<Real> & nodes,
const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type);
/// pre compute all shapes on the element integration points from natural coordinates
template <ElementType type>
void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type);
/// pre compute all shapes on the element integration points from natural coordinates
template <ElementType type>
void precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type);
/// interpolate nodal values on the integration points
template <ElementType type>
void interpolateOnIntegrationPoints(const Array<Real> &u,
Array<Real> &uq,
UInt nb_degree_of_freedom,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter,
bool accumulate = false,
UInt id_shape = 0,
UInt num_degre_of_freedom_to_interpolate = 0,
UInt num_degre_of_freedom_interpolated = 0) const;
/// compute the gradient of u on the integration points
template <ElementType type>
void gradientOnIntegrationPoints(const Array<Real> &u,
Array<Real> &nablauq,
UInt nb_degree_of_freedom,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter,
bool accumulate = false,
UInt id_shape = 0,
UInt num_degre_of_freedom_to_interpolate = 0,
UInt num_degre_of_freedom_interpolated = 0) const;
/// multiply a field by shape functions
template <ElementType type>
void fieldTimesShapes(__attribute__((unused)) const Array<Real> & field,
__attribute__((unused)) Array<Real> & fiedl_times_shapes,
__attribute__((unused)) const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
private:
/// extract the nodal field value to fill an elemental field
template <ElementType type>
void extractNodalToElementField(const Array<Real> & nodal_f,
Array<Real> & elemental_f,
UInt num_degre_of_freedom_to_extract,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get a the shapes vector
inline const Array<Real> & getShapes(const ElementType & type,
const GhostType & ghost_type,
UInt id = 0) const;
/// get a the shapes derivatives vector
inline const Array<Real> & getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type,
UInt id = 0) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// shape functions for all elements
ElementTypeMapMultiReal shapes;
/// shape derivatives for all elements
ElementTypeMapMultiReal shapes_derivatives;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "shape_linked_inline_impl.cc"
#endif
/// standard output stream operator
// inline std::ostream & operator <<(std::ostream & stream, const ShapeLinked & _this)
// {
// _this.printself(stream);
// return stream;
// }
__END_AKANTU__
#endif /* __AKANTU_SHAPE_LINKED_HH__ */
diff --git a/src/fe_engine/shape_linked_inline_impl.cc b/src/fe_engine/shape_linked_inline_impl.cc
index d13ec494f..6e4133b73 100644
--- a/src/fe_engine/shape_linked_inline_impl.cc
+++ b/src/fe_engine/shape_linked_inline_impl.cc
@@ -1,331 +1,332 @@
/**
* @file shape_linked_inline_impl.cc
*
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Jul 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Mon Dec 13 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief ShapeLinked inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
template <ElementKind kind>
inline void
ShapeLinked<kind>::initShapeFunctions(const Array<Real> & nodes,
const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
#undef INIT_SHAPE_FUNCTIONS
/* -------------------------------------------------------------------------- */
#define INIT_SHAPE_FUNCTIONS(type) \
setIntegrationPointsByType<type>(integration_points, ghost_type); \
precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type); \
precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
#if defined(AKANTU_STRUCTURAL_MECHANICS)
template <>
inline void
ShapeLinked<_ek_structural>::initShapeFunctions(__attribute__((unused)) const Array<Real> & nodes,
__attribute__((unused)) const Matrix<Real> & integration_points,
__attribute__((unused)) const ElementType & type,
__attribute__((unused)) const GhostType & ghost_type) {
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
}
#endif
#undef INIT_SHAPE_FUNCTIONS
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
inline const Array<Real> & ShapeLinked<kind>::getShapes(const ElementType & type,
const GhostType & ghost_type,
UInt id) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(shapes.exists(type, ghost_type),
"No shapes of type "
<< type << " in " << this->id);
AKANTU_DEBUG_OUT();
return *(shapes(type, ghost_type)[id]);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
inline const Array<Real> & ShapeLinked<kind>::getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type,
UInt id) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(shapes_derivatives.exists(type, ghost_type),
"No shapes_derivatives of type "
<< type << " in " << this->id);
AKANTU_DEBUG_OUT();
return *(shapes_derivatives(type, ghost_type)[id]);
}
#if defined(AKANTU_STRUCTURAL_MECHANICS)
/* -------------------------------------------------------------------------- */
template <>
template <ElementType type>
void ShapeLinked<_ek_structural>::precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
// Real * coord = mesh.getNodes().storage();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
Matrix<Real> & natural_coords = integration_points(type, ghost_type);
UInt nb_points = integration_points(type, ghost_type).cols();
UInt size_of_shapes = ElementClass<type>::getShapeSize();
std::string ghost = "";
if(ghost_type == _ghost) {
ghost = "ghost_";
}
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt nb_shape_functions = ElementClass<type, _ek_structural>::getNbShapeFunctions();
Array<Real> ** shapes_tmp = new Array<Real> *[nb_shape_functions];
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el,
type, ghost_type);
for (UInt s = 0; s < nb_shape_functions; ++s) {
std::stringstream sstr_shapes;
sstr_shapes << id << ":" << ghost << "shapes:" << type << ":" << s;
shapes_tmp[s] = &(alloc<Real>(sstr_shapes.str(),
nb_element*nb_points,
size_of_shapes));
Array<Real>::matrix_iterator x_it = x_el.begin(spatial_dimension,
nb_nodes_per_element);
Array<Real>::matrix_iterator shapes_it =
shapes_tmp[s]->begin_reinterpret(size_of_shapes, nb_points, nb_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++shapes_it, ++x_it) {
Matrix<Real> & X = *x_it;
Matrix<Real> & N = *shapes_it;
ElementClass<type>::computeShapes(natural_coords,
N, X,
s);
}
}
shapes(type, ghost_type) = shapes_tmp;
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLinked<kind>::precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
// Real * coord = mesh.getNodes().storage();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt natural_spatial_dimension = ElementClass<type>::getNaturalSpaceDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
Matrix<Real> & natural_coords = integration_points(type, ghost_type);
UInt nb_points = natural_coords.cols();
UInt nb_element = mesh.getNbElement(type, ghost_type);
std::string ghost = "";
if(ghost_type == _ghost) {
ghost = "ghost_";
}
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el,
type, ghost_type);
UInt nb_shape_functions = ElementClass<type>::getNbShapeDerivatives();
Array<Real> ** shapes_derivatives_tmp = new Array<Real> *[nb_shape_functions];
for (UInt s = 0; s < nb_shape_functions; ++s) {
std::stringstream sstr_shapesd;
sstr_shapesd << id << ":" << ghost << "shapes_derivatives:" << type << ":" << s;
shapes_derivatives_tmp[s] = &(alloc<Real>(sstr_shapesd.str(),
nb_element*nb_points,
size_of_shapesd));
Real * shapesd_val = shapes_derivatives_tmp[s]->storage();
Array<Real>::matrix_iterator x_it = x_el.begin(spatial_dimension,
nb_nodes_per_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
// compute shape derivatives
Matrix<Real> & X = *x_it;
Tensor3<Real> B(shapesd_val,
natural_spatial_dimension, nb_nodes_per_element, nb_points);
ElementClass<type>::computeShapeDerivatives(natural_coords,
B, X, s);
shapesd_val += size_of_shapesd*nb_points;
}
}
shapes_derivatives(type, ghost_type) = shapes_derivatives_tmp;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLinked<kind>::extractNodalToElementField(const Array<Real> & nodal_f,
Array<Real> & elemental_f,
UInt num_degre_of_freedom_to_extract,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const{
AKANTU_DEBUG_IN();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_degree_of_freedom = nodal_f.getNbComponent();
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
}
elemental_f.resize(nb_element);
Real * nodal_f_val = nodal_f.storage();
Real * f_val = elemental_f.storage();
UInt * el_conn;
for (UInt el = 0; el < nb_element; ++el) {
if(filter_elements != empty_filter) el_conn = conn_val + filter_elements(el) * nb_nodes_per_element;
else el_conn = conn_val + el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = *(el_conn + n);
*f_val = nodal_f_val[node * nb_degree_of_freedom + num_degre_of_freedom_to_extract];
f_val += 1;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLinked<kind>::interpolateOnIntegrationPoints(const Array<Real> &in_u,
Array<Real> &out_uq,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements,
bool accumulate,
UInt id_shape,
UInt num_degre_of_freedom_to_interpolate,
UInt num_degre_of_freedom_interpolated) const {
AKANTU_DEBUG_IN();
Array<Real> * shapes_loc = shapes(type, ghost_type)[id_shape];
AKANTU_DEBUG_ASSERT(shapes_loc != NULL,
"No shapes for the type " << type);
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
Array<Real> u_el(0, nb_nodes_per_element);
extractNodalToElementField<type>(in_u, u_el, num_degre_of_freedom_to_interpolate,
ghost_type, filter_elements);
if(!accumulate) out_uq.clear();
UInt nb_points = integration_points(type, ghost_type).cols() * u_el.getSize();
Array<Real> uq(nb_points, 1, 0.);
this->template interpolateElementalFieldOnIntegrationPoints<type>(u_el,
uq,
ghost_type,
*shapes_loc,
filter_elements);
for (UInt q = 0; q < nb_points; ++q) {
out_uq(q, num_degre_of_freedom_to_interpolate) += uq(q);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLinked<kind>::gradientOnIntegrationPoints(const Array<Real> &in_u,
Array<Real> &out_nablauq,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements,
bool accumulate,
UInt id_shape,
UInt num_degre_of_freedom_to_interpolate,
UInt num_degre_of_freedom_interpolated) const {
AKANTU_DEBUG_IN();
Array<Real> * shapesd_loc = shapes_derivatives(type, ghost_type)[id_shape];
AKANTU_DEBUG_ASSERT(shapesd_loc != NULL,
"No shapes for the type " << type);
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
Array<Real> u_el(0, nb_nodes_per_element);
extractNodalToElementField<type>(in_u, u_el, num_degre_of_freedom_to_interpolate, ghost_type, filter_elements);
UInt nb_points = integration_points(type, ghost_type).cols() * u_el.getSize();
UInt element_dimension = ElementClass<type>::getSpatialDimension();
Array<Real> nablauq(nb_points, element_dimension, 0.);
if(!accumulate) out_nablauq.clear();
this->template gradientElementalFieldOnIntegrationPoints<type>(u_el,
nablauq,
ghost_type,
*shapesd_loc,
filter_elements);
Array<Real>::matrix_iterator nabla_u_it = nablauq.begin(1, element_dimension);
Array<Real>::matrix_iterator out_nabla_u_it = out_nablauq.begin(nb_degree_of_freedom, element_dimension);
for (UInt q = 0; q < nb_points; ++q, ++nabla_u_it, ++out_nabla_u_it) {
for (UInt s = 0; s < element_dimension; ++s) {
(*out_nabla_u_it)(num_degre_of_freedom_to_interpolate, s) += (*nabla_u_it)(0, s);
}
}
AKANTU_DEBUG_OUT();
}
diff --git a/src/geometry/aabb_primitives/aabb_primitive.cc b/src/geometry/aabb_primitives/aabb_primitive.cc
index 6d5324f33..3a511c8bc 100644
--- a/src/geometry/aabb_primitives/aabb_primitive.cc
+++ b/src/geometry/aabb_primitives/aabb_primitive.cc
@@ -1,48 +1,49 @@
/**
* @file aabb_primitive.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
- * @date creation: Tue Jun 2 2015
- * @date last modification: Tue Jun 2 2015
+ * @date creation: Fri Jan 04 2013
+ * @date last modification: Thu Jan 14 2016
*
* @brief Macro classe (primitive) for AABB CGAL algos
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aabb_primitive.hh"
__BEGIN_AKANTU__
Triangle_primitive::Point Triangle_primitive::reference_point() const {
return primitive.vertex(0);
}
Line_arc_primitive::Point Line_arc_primitive::reference_point() const {
Real x = to_double(primitive.source().x());
Real y = to_double(primitive.source().y());
Real z = to_double(primitive.source().z());
return Spherical::Point_3(x, y, z);
}
__END_AKANTU__
diff --git a/src/geometry/aabb_primitives/aabb_primitive.hh b/src/geometry/aabb_primitives/aabb_primitive.hh
index e40a83bb9..aadefaf24 100644
--- a/src/geometry/aabb_primitives/aabb_primitive.hh
+++ b/src/geometry/aabb_primitives/aabb_primitive.hh
@@ -1,89 +1,90 @@
/**
* @file aabb_primitive.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Fri Mar 13 2015
- * @date last modification: Fri Mar 13 2015
+ * @date last modification: Thu Jan 14 2016
*
* @brief Macro classe (primitive) for AABB CGAL algos
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AABB_PRIMITIVE_HH__
#define __AKANTU_AABB_PRIMITIVE_HH__
#include "aka_common.hh"
#include "line_arc.hh"
#include "triangle.hh"
#include "tetrahedron.hh"
#include "mesh_geom_common.hh"
__BEGIN_AKANTU__
/**
* This macro defines a class that is used in the CGAL AABB tree algorithm.
* All the `typedef`s and methods are required by the AABB module.
*
* The member variables are
* - the id of the element associated to the primitive
* - the geometric primitive of the element
*
* @param name the name of the primitive type
* @param kernel the name of the kernel used
*/
#define AKANTU_AABB_CLASS(name, kernel) \
class name##_primitive { \
typedef std::list< name<kernel> >::iterator Iterator; \
\
public: \
typedef UInt Id; \
typedef kernel::Point_3 Point; \
typedef kernel::name##_3 Datum; \
\
public: \
name##_primitive() : meshId(0), primitive() {} \
name##_primitive(Iterator it) : meshId(it->id()), primitive(*it) {} \
\
public: \
const Datum & datum() const { return primitive; } \
Point reference_point() const; \
const Id & id() const { return meshId; } \
\
protected: \
Id meshId; \
name<kernel> primitive; \
\
}
// If the primitive is supported by CGAL::intersection() then the
// implementation process is really easy with this macro
AKANTU_AABB_CLASS(Triangle, Cartesian);
AKANTU_AABB_CLASS(Line_arc, Spherical);
#undef AKANTU_AABB_CLASS
__END_AKANTU__
#endif // __AKANTU_AABB_PRIMITIVE_HH__
diff --git a/src/geometry/aabb_primitives/line_arc.hh b/src/geometry/aabb_primitives/line_arc.hh
index ad62a644b..71bcd5d09 100644
--- a/src/geometry/aabb_primitives/line_arc.hh
+++ b/src/geometry/aabb_primitives/line_arc.hh
@@ -1,78 +1,78 @@
/**
- * @file segment.hh
+ * @file line_arc.hh
*
- * @author Clément Roux-Langlois <clement.roux@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
- * @date creation: Wed Mar 13 2015
- * @date last modification: Wed Mar 13 2015
+ * @date creation: Fri Jan 04 2013
+ * @date last modification: Thu Jan 14 2016
*
* @brief Segment classe (geometry) for AABB CGAL algos
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_LINE_ARC_HH__
#define __AKANTU_LINE_ARC_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/// Class used for substitution of CGAL::Triangle_3 primitive
template<typename K>
class Line_arc : public CGAL::Line_arc_3<K> {
public:
/// Default constructor
Line_arc() :
CGAL::Line_arc_3<K>(), mesh_id(0), seg_id(0) {}
/// Copy constructor
Line_arc(const Line_arc & other) :
CGAL::Line_arc_3<K>(other), mesh_id(other.mesh_id), seg_id(other.seg_id) {}
/// Construct from 3 points
// "CGAL-4.5/doc_html/Circular_kernel_3/classCGAL_1_1Line__arc__3.html"
Line_arc(const CGAL::Line_3<K> & l, const CGAL::Circular_arc_point_3<K> & a,
const CGAL::Circular_arc_point_3<K> & b):
CGAL::Line_arc_3<K>(l, a, b), mesh_id(0), seg_id(0) {}
public:
UInt id() const { return mesh_id; }
UInt segId() const { return seg_id; }
void setId(UInt newId) { mesh_id = newId; }
void setSegId(UInt newId) { seg_id = newId; }
protected:
/// Id of the element represented by the primitive
UInt mesh_id;
/// Id of the segment represented by the primitive
UInt seg_id;
};
__END_AKANTU__
#endif // __AKANTU_LINE_ARC_HH__
diff --git a/src/geometry/aabb_primitives/tetrahedron.hh b/src/geometry/aabb_primitives/tetrahedron.hh
index d0efeb7b4..cc309ba07 100644
--- a/src/geometry/aabb_primitives/tetrahedron.hh
+++ b/src/geometry/aabb_primitives/tetrahedron.hh
@@ -1,74 +1,74 @@
/**
* @file tetrahedron.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Tue Mar 10 2015
- * @date last modification: Tue Mar 10 2015
+ * @date creation: Fri Feb 27 2015
+ * @date last modification: Thu Jan 14 2016
*
* @brief Tetrahedron classe (geometry) for AABB CGAL algos
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TETRAHEDRON_HH__
#define __AKANTU_TETRAHEDRON_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/// Class used for substitution of CGAL::Tetrahedron_3 primitive
template<typename K>
class Tetrahedron : public CGAL::Tetrahedron_3<K> {
public:
/// Default constructor
Tetrahedron() :
CGAL::Tetrahedron_3<K>(), meshId(0) {}
/// Copy constructor
Tetrahedron(const Tetrahedron & other) :
CGAL::Tetrahedron_3<K>(other), meshId(other.meshId) {}
/// Construct from 4 points
Tetrahedron(const CGAL::Point_3<K> & a,
const CGAL::Point_3<K> & b,
const CGAL::Point_3<K> & c,
const CGAL::Point_3<K> & d) :
CGAL::Tetrahedron_3<K>(a, b, c, d), meshId(0) {}
public:
UInt id() const { return meshId; }
void setId(UInt newId) { meshId = newId; }
protected:
/// Id of the element represented by the primitive
UInt meshId;
};
__END_AKANTU__
#endif
diff --git a/src/geometry/aabb_primitives/triangle.hh b/src/geometry/aabb_primitives/triangle.hh
index 559285561..9243e73d0 100644
--- a/src/geometry/aabb_primitives/triangle.hh
+++ b/src/geometry/aabb_primitives/triangle.hh
@@ -1,71 +1,71 @@
/**
* @file triangle.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Tue Mar 3 2015
- * @date last modification: Tue Mar 3 2015
+ * @date creation: Fri Jan 04 2013
+ * @date last modification: Thu Jan 14 2016
*
* @brief Triangle classe (geometry) for AABB CGAL algos
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TRIANGLE_HH__
#define __AKANTU_TRIANGLE_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/// Class used for substitution of CGAL::Triangle_3 primitive
template<typename K>
class Triangle : public CGAL::Triangle_3<K> {
public:
/// Default constructor
Triangle() :
CGAL::Triangle_3<K>(), meshId(0) {}
/// Copy constructor
Triangle(const Triangle & other) :
CGAL::Triangle_3<K>(other), meshId(other.meshId) {}
/// Construct from 3 points
Triangle(const CGAL::Point_3<K> & a, const CGAL::Point_3<K> & b, const CGAL::Point_3<K> & c):
CGAL::Triangle_3<K>(a, b, c), meshId(0) {}
public:
UInt id() const { return meshId; }
void setId(UInt newId) { meshId = newId; }
protected:
/// Id of the element represented by the primitive
UInt meshId;
};
__END_AKANTU__
#endif // __AKANTU_TRIANGLE_HH__
diff --git a/src/geometry/geom_helper_functions.hh b/src/geometry/geom_helper_functions.hh
index 7abf04112..fbe6bbaca 100644
--- a/src/geometry/geom_helper_functions.hh
+++ b/src/geometry/geom_helper_functions.hh
@@ -1,103 +1,104 @@
/**
* @file geom_helper_functions.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
- * @date creation: Wed Mar 4 2015
- * @date last modification: Thu Mar 5 2015
+ * @date creation: Fri Jan 04 2013
+ * @date last modification: Thu Jan 14 2016
*
* @brief Helper functions for the computational geometry algorithms
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef _AKANTU_GEOM_HELPER_FUNCTIONS_HH__
#define _AKANTU_GEOM_HELPER_FUNCTIONS_HH__
#include "aka_common.hh"
#include "aka_math.hh"
#include "tree_type_helper.hh"
#include "mesh_geom_common.hh"
__BEGIN_AKANTU__
/// Fuzzy compare of two points
template <class Point>
inline bool comparePoints(const Point & a, const Point & b) {
return Math::are_float_equal(a.x(), b.x()) &&
Math::are_float_equal(a.y(), b.y()) &&
Math::are_float_equal(a.z(), b.z());
}
template <>
inline bool comparePoints(const Spherical::Circular_arc_point_3 & a,
const Spherical::Circular_arc_point_3 & b) {
return Math::are_float_equal(CGAL::to_double(a.x()), CGAL::to_double(b.x())) &&
Math::are_float_equal(CGAL::to_double(a.y()), CGAL::to_double(b.y())) &&
Math::are_float_equal(CGAL::to_double(a.z()), CGAL::to_double(b.z()));
}
/// Fuzzy compare of two segments
template <class K>
inline bool compareSegments(const CGAL::Segment_3<K> & a, const CGAL::Segment_3<K> & b) {
return (comparePoints(a.source(), b.source()) && comparePoints(a.target(), b.target())) ||
(comparePoints(a.source(), b.target()) && comparePoints(a.target(), b.source()));
}
typedef Cartesian K;
/// Compare segment pairs
inline bool compareSegmentPairs(const std::pair<K::Segment_3, UInt> & a, const std::pair<K::Segment_3, UInt> & b) {
return compareSegments(a.first, b.first);
}
/// Pair ordering operator based on first member
struct segmentPairsLess {
inline bool operator()(const std::pair<K::Segment_3, UInt> & a, const std::pair<K::Segment_3, UInt> & b) {
return CGAL::compare_lexicographically(a.first.min(), b.first.min()) || CGAL::compare_lexicographically(a.first.max(), b.first.max());
}
};
/* -------------------------------------------------------------------------- */
/* Predicates */
/* -------------------------------------------------------------------------- */
/// Predicate used to determine if two segments are equal
class IsSameSegment {
public:
IsSameSegment(const K::Segment_3 & segment):
segment(segment)
{}
bool operator()(const std::pair<K::Segment_3, UInt> & test_pair) {
return compareSegments(segment, test_pair.first);
}
protected:
const K::Segment_3 segment;
};
__END_AKANTU__
#endif // _AKANTU_GEOM_HELPER_FUNCTIONS_HH__
diff --git a/src/geometry/mesh_abstract_intersector.hh b/src/geometry/mesh_abstract_intersector.hh
index 43c4244e9..ea54bba64 100644
--- a/src/geometry/mesh_abstract_intersector.hh
+++ b/src/geometry/mesh_abstract_intersector.hh
@@ -1,106 +1,108 @@
/**
- * @file mesh_abstract_intersector.hh
+ * @file mesh_abstract_intersector.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Mon Jul 13 2015
- * @date last modification: Mon Jul 13 2015
+ * @date creation: Wed Apr 29 2015
+ * @date last modification: Thu Jan 14 2016
*
- * @brief Abstract class for intersection computations
+ * @brief Abstract class for intersection computations
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#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 Query>
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<UInt> &);
/// get the intersection_points array
AKANTU_GET_MACRO(IntersectionPoints, intersection_points, const Array<Real> *);
/// get the nb_seg_by_el UInt
AKANTU_GET_MACRO(NbSegByEl, nb_seg_by_el, const 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> & query_list);
/// Compute intersection points between the mesh and a list of queries
virtual void computeMeshQueryListIntersectionPoint(const std::list<Query> & 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> & 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<UInt> * new_node_per_elem;
/// intersection output: new intersection points (computeMeshQueryListIntersectionPoint)
Array<Real> * 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/geometry/mesh_abstract_intersector_tmpl.hh b/src/geometry/mesh_abstract_intersector_tmpl.hh
index d40fcaedf..9782cee04 100644
--- a/src/geometry/mesh_abstract_intersector_tmpl.hh
+++ b/src/geometry/mesh_abstract_intersector_tmpl.hh
@@ -1,87 +1,89 @@
/**
- * @file mesh_abstract_intersector_tmpl.hh
+ * @file mesh_abstract_intersector_tmpl.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Mon Jul 13 2015
- * @date last modification: Mon Jul 13 2015
+ * @date creation: Wed Apr 29 2015
+ * @date last modification: Thu Jan 14 2016
*
- * @brief General class for intersection computations
+ * @brief General class for intersection computations
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
#define __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
#include "aka_common.hh"
#include "mesh_abstract_intersector.hh"
__BEGIN_AKANTU__
template<class Query>
MeshAbstractIntersector<Query>::MeshAbstractIntersector(Mesh & mesh):
MeshGeomAbstract(mesh),
new_node_per_elem(NULL),
intersection_points(NULL),
nb_seg_by_el(0)
{}
template<class Query>
MeshAbstractIntersector<Query>::~MeshAbstractIntersector()
{}
template<class Query>
void MeshAbstractIntersector<Query>::computeIntersectionQueryList(
const std::list<Query> & query_list) {
AKANTU_DEBUG_IN();
typename std::list<Query>::const_iterator
query_it = query_list.begin(),
query_end = query_list.end();
for (; query_it != query_end ; ++query_it) {
computeIntersectionQuery(*query_it);
}
AKANTU_DEBUG_OUT();
}
template<class Query>
void MeshAbstractIntersector<Query>::computeMeshQueryListIntersectionPoint(
const std::list<Query> & query_list, UInt nb_old_nodes) {
AKANTU_DEBUG_IN();
typename std::list<Query>::const_iterator
query_it = query_list.begin(),
query_end = query_list.end();
for (; query_it != query_end ; ++query_it) {
computeMeshQueryIntersectionPoint(*query_it, nb_old_nodes);
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
#endif // __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/mesh_geom_abstract.hh b/src/geometry/mesh_geom_abstract.hh
index 41af4f4ed..9ab8ff286 100644
--- a/src/geometry/mesh_geom_abstract.hh
+++ b/src/geometry/mesh_geom_abstract.hh
@@ -1,64 +1,65 @@
/**
* @file mesh_geom_abstract.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Thu Feb 26 2015
- * @date last modification: Fri Mar 6 2015
+ * @date creation: Fri Jan 04 2013
+ * @date last modification: Thu Jan 14 2016
*
* @brief Class for constructing the CGAL primitives of a mesh
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_GEOM_ABSTRACT_HH__
#define __AKANTU_MESH_GEOM_ABSTRACT_HH__
#include "aka_common.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/// Abstract class for mesh geometry operations
class MeshGeomAbstract {
public:
/// Construct from mesh
explicit MeshGeomAbstract(Mesh & mesh) : mesh(mesh) {};
/// Destructor
virtual ~MeshGeomAbstract() {};
public:
/// Construct geometric data for computational geometry algorithms
virtual void constructData(GhostType ghost_type = _not_ghost) = 0;
protected:
/// Mesh used to construct the primitives
Mesh & mesh;
};
__END_AKANTU__
#endif // __AKANTU_MESH_GEOM_ABSTRACT_HH__
diff --git a/src/geometry/mesh_geom_common.hh b/src/geometry/mesh_geom_common.hh
index 8ad6b8314..71bf57609 100644
--- a/src/geometry/mesh_geom_common.hh
+++ b/src/geometry/mesh_geom_common.hh
@@ -1,53 +1,54 @@
/**
- * @file mesh_geom_common.hh
+ * @file mesh_geom_common.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
- * @date creation: Wed May 13 2015
- * @date last modification: Wed May 13 2015
+ * @date creation: Fri Jan 04 2013
+ * @date last modification: Thu Jan 14 2016
*
- * @brief Common file for MeshGeom module
+ * @brief Common file for MeshGeom module
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_MESH_GEOM_COMMON_HH__
#define __AKANTU_MESH_GEOM_COMMON_HH__
#include "aka_common.hh"
#include <CGAL/MP_Float.h>
#include <CGAL/Quotient.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Spherical_kernel_3.h>
#include <CGAL/Algebraic_kernel_for_spheres_2_3.h>
__BEGIN_AKANTU__
typedef CGAL::Simple_cartesian<Real> Cartesian;
typedef CGAL::Quotient<CGAL::MP_Float> NT;
typedef CGAL::Spherical_kernel_3<CGAL::Simple_cartesian<NT>, CGAL::Algebraic_kernel_for_spheres_2_3<NT> > Spherical;
__END_AKANTU__
#endif // __AKANTU_MESH_GEOM_COMMON_HH__
diff --git a/src/geometry/mesh_geom_factory.hh b/src/geometry/mesh_geom_factory.hh
index fa48e19e3..74c464368 100644
--- a/src/geometry/mesh_geom_factory.hh
+++ b/src/geometry/mesh_geom_factory.hh
@@ -1,107 +1,108 @@
/**
* @file mesh_geom_factory.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Thu Feb 26 2015
- * @date last modification: Fri Mar 6 2015
+ * @date creation: Fri Feb 27 2015
+ * @date last modification: Thu Jan 14 2016
*
* @brief Class for constructing the CGAL primitives of a mesh
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_GEOM_FACTORY_HH__
#define __AKANTU_MESH_GEOM_FACTORY_HH__
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_geom_abstract.hh"
#include "tree_type_helper.hh"
#include "geom_helper_functions.hh"
#include <algorithm>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
* @brief Class used to construct AABB tree for intersection computations
*
* This class constructs a CGAL AABB tree of one type of element in a mesh
* for fast intersection computations.
*/
template<UInt dim, ElementType el_type, class Primitive, class Kernel>
class MeshGeomFactory : public MeshGeomAbstract {
public:
/// Construct from mesh
explicit MeshGeomFactory(Mesh & mesh);
/// Desctructor
virtual ~MeshGeomFactory();
public:
/// Construct AABB tree for fast intersection computing
virtual void constructData(GhostType ghost_type = _not_ghost);
/**
* @brief Construct a primitive and add it to a list of primitives
*
* This function needs to be specialized for every type that is wished to be supported.
* @param node_coordinates coordinates of the nodes making up the element
* @param id element number
* @param list the primitive list (not used inside MeshGeomFactory)
*/
inline void addPrimitive(
const Matrix<Real> & node_coordinates,
UInt id,
typename TreeTypeHelper<Primitive, Kernel>::container_type & list
);
inline void addPrimitive(
const Matrix<Real> & node_coordinates,
UInt id
);
/// Getter for the AABB tree
const typename TreeTypeHelper<Primitive, Kernel>::tree & getTree() const { return *data_tree; }
/// Getter for primitive list
const typename TreeTypeHelper<Primitive, Kernel>::container_type & getPrimitiveList() const
{ return primitive_list; }
protected:
/// AABB data tree
typename TreeTypeHelper<Primitive, Kernel>::tree * data_tree;
/// Primitive list
typename TreeTypeHelper<Primitive, Kernel>::container_type primitive_list;
};
__END_AKANTU__
#include "mesh_geom_factory_tmpl.hh"
#endif // __AKANTU_MESH_GEOM_FACTORY_HH__
diff --git a/src/geometry/mesh_geom_factory_tmpl.hh b/src/geometry/mesh_geom_factory_tmpl.hh
index 222654b94..9f2450e3b 100644
--- a/src/geometry/mesh_geom_factory_tmpl.hh
+++ b/src/geometry/mesh_geom_factory_tmpl.hh
@@ -1,257 +1,259 @@
/**
* @file mesh_geom_factory_tmpl.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Thu Feb 26 2015
- * @date last modification: Fri Mar 6 2015
+ * @date creation: Fri Feb 27 2015
+ * @date last modification: Thu Jan 14 2016
*
* @brief Class for constructing the CGAL primitives of a mesh
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
#define __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_geom_common.hh"
#include "mesh_geom_factory.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
template<UInt dim, ElementType type, class Primitive, class Kernel>
MeshGeomFactory<dim, type, Primitive, Kernel>::MeshGeomFactory(Mesh & mesh) :
MeshGeomAbstract(mesh),
data_tree(NULL),
primitive_list()
{}
template<UInt dim, ElementType type, class Primitive, class Kernel>
MeshGeomFactory<dim, type, Primitive, Kernel>::~MeshGeomFactory() {
delete data_tree;
}
/**
* This function loops over the elements of `type` in the mesh and creates the
* AABB tree of geometrical primitves (`data_tree`).
*/
template<UInt dim, ElementType type, class Primitive, class Kernel>
void MeshGeomFactory<dim, type, Primitive, Kernel>::constructData(GhostType ghost_type) {
AKANTU_DEBUG_IN();
primitive_list.clear();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
const Array<Real> & nodes = mesh.getNodes();
UInt el_index = 0;
Array<UInt>::const_vector_iterator it = connectivity.begin(nb_nodes_per_element);
Array<UInt>::const_vector_iterator end = connectivity.end(nb_nodes_per_element);
Matrix<Real> node_coordinates(dim, nb_nodes_per_element);
// This loop builds the list of primitives
for (; it != end ; ++it, ++el_index) {
const Vector<UInt> & el_connectivity = *it;
for (UInt i = 0 ; i < nb_nodes_per_element ; i++)
for (UInt j = 0 ; j < dim ; j++)
node_coordinates(j, i) = nodes(el_connectivity(i), j);
// the unique elemental id assigned to the primitive is the
// linearized element index over ghost type
addPrimitive(node_coordinates, el_index);
}
delete data_tree;
// This condition allows the use of the mesh geom module
// even if types are not compatible with AABB tree algorithm
if (TreeTypeHelper<Primitive, Kernel>::is_valid)
data_tree = new typename TreeTypeHelper<Primitive, Kernel>::tree(primitive_list.begin(), primitive_list.end());
AKANTU_DEBUG_OUT();
}
template<UInt dim, ElementType type, class Primitive, class Kernel>
void MeshGeomFactory<dim, type, Primitive, Kernel>::addPrimitive(const Matrix<Real> & node_coordinates,
UInt id) {
this->addPrimitive(node_coordinates, id, this->primitive_list);
}
// (2D, _triangle_3) decomposed into Triangle<Cartesian>
template<>
inline void MeshGeomFactory<2, _triangle_3, Triangle<Cartesian>, Cartesian>::addPrimitive(
const Matrix<Real> & node_coordinates,
UInt id,
TreeTypeHelper<Triangle<Cartesian>, Cartesian>::container_type & list) {
TreeTypeHelper<Triangle<Cartesian>, Cartesian>::point_type
a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
Triangle<Cartesian> t(a, b, c);
t.setId(id);
list.push_back(t);
}
// (2D, _triangle_6) decomposed into Triangle<Cartesian>
template<>
inline void MeshGeomFactory<2, _triangle_6, Triangle<Cartesian>, Cartesian>::addPrimitive(
const Matrix<Real> & node_coordinates,
UInt id,
TreeTypeHelper<Triangle<Cartesian>, Cartesian>::container_type & list) {
TreeTypeHelper<Triangle<Cartesian>, Cartesian>::point_type
a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
Triangle<Cartesian> t(a, b, c);
t.setId(id);
list.push_back(t);
}
// (2D, _triangle_3) decomposed into Line_arc<Spherical>
template<>
inline void MeshGeomFactory<2, _triangle_3, Line_arc<Spherical>, Spherical>::addPrimitive(
const Matrix<Real> & node_coordinates,
UInt id,
TreeTypeHelper<Line_arc<Spherical>, Spherical>::container_type & list) {
TreeTypeHelper<Line_arc<Spherical>, Spherical>::point_type
a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
/*std::cout << "elem " << id << " node 1 : x_node=" << node_coordinates(0, 0)
<< ", x_arc_node=" << a.x() << ", y_node=" << node_coordinates(1, 0)
<< ", y_arc_node=" << a.y() << std::endl ;
std::cout << "elem " << id << " node 2 : x_node=" << node_coordinates(0, 1)
<< ", x_arc_node=" << b.x() << ", y_node=" << node_coordinates(1, 1)
<< ", y_arc_node=" << b.y() << std::endl ;
std::cout << "elem " << id << " node 2 : x_node=" << node_coordinates(0, 2)
<< ", x_arc_node=" << c.x() << ", y_node=" << node_coordinates(1, 2)
<< ", y_arc_node=" << c.y() << std::endl ;*/
CGAL::Line_3<Spherical> l1(a, b), l2(b, c), l3(c, a);
Line_arc<Spherical> s1(l1,a, b), s2(l2, b, c), s3(l3, c, a);
s1.setId(id); s1.setSegId(0);
s2.setId(id); s2.setSegId(1);
s3.setId(id); s3.setSegId(2);
list.push_back(s1);
list.push_back(s2);
list.push_back(s3);
}
#if defined(AKANTU_IGFEM)
// (2D, _igfem_triangle_4) decomposed into Line_arc<Spherical>
template<>
inline void MeshGeomFactory<2, _igfem_triangle_4, Line_arc<Spherical>, Spherical>::addPrimitive(
const Matrix<Real> & node_coordinates,
UInt id,
TreeTypeHelper<Line_arc<Spherical>, Spherical>::container_type & list) {
TreeTypeHelper<Line_arc<Spherical>, Spherical>::point_type
a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
CGAL::Line_3<Spherical> l1(a, b), l2(b, c), l3(c, a);
Line_arc<Spherical> s1(l1,a, b), s2(l2, b, c), s3(l3, c, a);
s1.setId(id); s1.setSegId(0);
s2.setId(id); s2.setSegId(1);
s3.setId(id); s3.setSegId(2);
list.push_back(s1);
list.push_back(s2);
list.push_back(s3);
}
// (2D, _igfem_triangle_4) decomposed into Line_arc<Spherical>
template<>
inline void MeshGeomFactory<2, _igfem_triangle_5, Line_arc<Spherical>, Spherical>::addPrimitive(
const Matrix<Real> & node_coordinates,
UInt id,
TreeTypeHelper<Line_arc<Spherical>, Spherical>::container_type & list) {
TreeTypeHelper<Line_arc<Spherical>, Spherical>::point_type
a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
CGAL::Line_3<Spherical> l1(a, b), l2(b, c), l3(c, a);
Line_arc<Spherical> s1(l1,a, b), s2(l2, b, c), s3(l3, c, a);
s1.setId(id); s1.setSegId(0);
s2.setId(id); s2.setSegId(1);
s3.setId(id); s3.setSegId(2);
list.push_back(s1);
list.push_back(s2);
list.push_back(s3);
}
#endif
// (3D, _tetrahedron_4) decomposed into Triangle<Cartesian>
template<>
inline void MeshGeomFactory<3, _tetrahedron_4, Triangle<Cartesian>, Cartesian>::addPrimitive(
const Matrix<Real> & node_coordinates,
UInt id,
TreeTypeHelper<Triangle<Cartesian>, Cartesian>::container_type & list) {
TreeTypeHelper<Triangle<Cartesian>, Cartesian>::point_type
a(node_coordinates(0, 0), node_coordinates(1, 0), node_coordinates(2, 0)),
b(node_coordinates(0, 1), node_coordinates(1, 1), node_coordinates(2, 1)),
c(node_coordinates(0, 2), node_coordinates(1, 2), node_coordinates(2, 2)),
d(node_coordinates(0, 3), node_coordinates(1, 3), node_coordinates(2, 3));
Triangle<Cartesian>
t1(a, b, c),
t2(b, c, d),
t3(c, d, a),
t4(d, a, b);
t1.setId(id);
t2.setId(id);
t3.setId(id);
t4.setId(id);
list.push_back(t1);
list.push_back(t2);
list.push_back(t3);
list.push_back(t4);
}
__END_AKANTU__
#endif // __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
diff --git a/src/geometry/mesh_geom_intersector.hh b/src/geometry/mesh_geom_intersector.hh
index 5fd3bfb2e..230d77249 100644
--- a/src/geometry/mesh_geom_intersector.hh
+++ b/src/geometry/mesh_geom_intersector.hh
@@ -1,70 +1,72 @@
/**
- * @file mesh_geom_intersector.hh
+ * @file mesh_geom_intersector.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Apr 29 2015
- * @date last modification: Wed Apr 29 2015
+ * @date last modification: Thu Jan 14 2016
*
- * @brief General class for intersection computations
+ * @brief General class for intersection computations
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_GEOM_INTERSECTOR_HH__
#define __AKANTU_MESH_GEOM_INTERSECTOR_HH__
#include "aka_common.hh"
#include "mesh_abstract_intersector.hh"
#include "mesh_geom_factory.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
* @brief Class used to perform intersections on a mesh and construct output data
*/
template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
class MeshGeomIntersector : public MeshAbstractIntersector<Query> {
public:
/// Construct from mesh
explicit MeshGeomIntersector(Mesh & mesh);
/// Destructor
virtual ~MeshGeomIntersector();
public:
/// Construct the primitive tree object
virtual void constructData(GhostType ghost_type = _not_ghost);
protected:
/// Factory object containing the primitive tree
MeshGeomFactory<dim, type, Primitive, Kernel> factory;
};
__END_AKANTU__
#include "mesh_geom_intersector_tmpl.hh"
#endif // __AKANTU_MESH_GEOM_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_geom_intersector_tmpl.hh b/src/geometry/mesh_geom_intersector_tmpl.hh
index 134b170fa..ec2454717 100644
--- a/src/geometry/mesh_geom_intersector_tmpl.hh
+++ b/src/geometry/mesh_geom_intersector_tmpl.hh
@@ -1,62 +1,62 @@
/**
- * @file mesh_geom_intersector_tmpl.hh
+ * @file mesh_geom_intersector_tmpl.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Wed Apr 29 2015
- * @date last modification: Wed Apr 29 2015
+ * @date last modification: Thu Jan 14 2016
*
- * @brief General class for intersection computations
+ * @brief General class for intersection computations
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
#define __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
#include "aka_common.hh"
#include "mesh_geom_intersector.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::MeshGeomIntersector(Mesh & mesh) :
MeshAbstractIntersector<Query>(mesh),
factory(mesh)
{}
template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::~MeshGeomIntersector()
{}
template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
void MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::constructData(GhostType ghost_type) {
this->intersection_points->resize(0);
factory.constructData(ghost_type);
}
__END_AKANTU__
#endif // __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/mesh_segment_intersector.hh b/src/geometry/mesh_segment_intersector.hh
index 48a20ee9b..66583a45f 100644
--- a/src/geometry/mesh_segment_intersector.hh
+++ b/src/geometry/mesh_segment_intersector.hh
@@ -1,101 +1,103 @@
/**
- * @file mesh_segment_intersector.hh
+ * @file mesh_segment_intersector.hh
*
- * @author Lucas Frerot
+ * @author Lucas Frerot <lucas.frerot@eplf.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Apr 29 2015
- * @date last modification: Wed Apr 29 2015
+ * @date last modification: Thu Jan 14 2016
*
- * @brief Computation of mesh intersection with segments
+ * @brief Computation of mesh intersection with segments
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_SEGMENT_INTERSECTOR_HH__
#define __AKANTU_MESH_SEGMENT_INTERSECTOR_HH__
#include "aka_common.hh"
#include "mesh_geom_intersector.hh"
#include "mesh_geom_common.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/// Here, we know what kernel we have to use
typedef Cartesian K;
template<UInt dim, ElementType type>
class MeshSegmentIntersector : public MeshGeomIntersector<dim, type, Triangle<K>, K::Segment_3, K> {
/// Parent class type
typedef MeshGeomIntersector<dim, type, Triangle<K>, K::Segment_3, K> parent_type;
/// Result of intersection function type
typedef typename IntersectionTypeHelper<TreeTypeHelper< Triangle<K>, K>, K::Segment_3>::intersection_type result_type;
/// Pair of segments and element id
typedef std::pair<K::Segment_3, UInt> pair_type;
public:
/// Construct from mesh
explicit MeshSegmentIntersector(Mesh & mesh, Mesh & result_mesh);
/// Destructor
virtual ~MeshSegmentIntersector();
public:
/**
* @brief Computes the intersection of the mesh with a segment
*
* @param query the segment to compute the intersections with the mesh
*/
virtual void computeIntersectionQuery(const K::Segment_3 & query);
/// Compute intersection points between the mesh and a query
virtual void computeMeshQueryIntersectionPoint(const K::Segment_3 & query, UInt nb_old_nodes);
/// Compute the embedded mesh
virtual void buildResultFromQueryList(const std::list<K::Segment_3> & query_list);
void setPhysicalName(const std::string & other)
{ current_physical_name = other; }
protected:
/// Compute segments from intersection list
void computeSegments(const std::list<result_type> & intersections,
std::set<pair_type, segmentPairsLess> & segments,
const K::Segment_3 & query);
protected:
/// Result mesh
Mesh & result_mesh;
/// Physical name of the current batch of queries
std::string current_physical_name;
};
__END_AKANTU__
#include "mesh_segment_intersector_tmpl.hh"
#endif // __AKANTU_MESH_SEGMENT_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_segment_intersector_tmpl.hh b/src/geometry/mesh_segment_intersector_tmpl.hh
index ca1cdcaea..22759680a 100644
--- a/src/geometry/mesh_segment_intersector_tmpl.hh
+++ b/src/geometry/mesh_segment_intersector_tmpl.hh
@@ -1,268 +1,270 @@
/**
- * @file mesh_segment_intersector_tmpl.hh
+ * @file mesh_segment_intersector_tmpl.hh
*
- * @author Lucas Frerot
+ * @author Lucas Frerot <lucas.frerot@eplf.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Apr 29 2015
- * @date last modification: Wed Apr 29 2015
+ * @date last modification: Thu Jan 14 2016
*
- * @brief Computation of mesh intersection with segments
+ * @brief Computation of mesh intersection with segments
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_SEGMENT_INTERSECTOR_TMPL_HH__
#define __AKANTU_MESH_SEGMENT_INTERSECTOR_TMPL_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
#include "tree_type_helper.hh"
__BEGIN_AKANTU__
template<UInt dim, ElementType type>
MeshSegmentIntersector<dim, type>::MeshSegmentIntersector(Mesh & mesh, Mesh & result_mesh):
parent_type(mesh),
result_mesh(result_mesh),
current_physical_name()
{
this->intersection_points = new Array<Real>(0,dim);
this->constructData();
}
template<UInt dim, ElementType type>
MeshSegmentIntersector<dim, type>::~MeshSegmentIntersector()
{}
template<UInt dim, ElementType type>
void MeshSegmentIntersector<dim, type>::computeIntersectionQuery(const K::Segment_3 & query) {
AKANTU_DEBUG_IN();
result_mesh.addConnectivityType(_segment_2, _not_ghost);
result_mesh.addConnectivityType(_segment_2, _ghost);
std::list<result_type> result_list;
std::set<std::pair<K::Segment_3, UInt>, segmentPairsLess> segment_set;
this->factory.getTree().all_intersections(query, std::back_inserter(result_list));
this->computeSegments(result_list, segment_set, query);
// Arrays for storing nodes and connectivity
Array<Real> & nodes = result_mesh.getNodes();
Array<UInt> & connectivity = result_mesh.getConnectivity(_segment_2);
// Arrays for storing associated element and physical name
bool valid_elemental_data = true;
Array<Element> * associated_element = NULL;
Array<std::string> * associated_physical_name = NULL;
try {
associated_element = &result_mesh.getData<Element>("associated_element", _segment_2);
associated_physical_name = &result_mesh.getData<std::string>("physical_names", _segment_2);
} catch (debug::Exception & e) {
valid_elemental_data = false;
}
std::set<pair_type, segmentPairsLess>::iterator
it = segment_set.begin(),
end = segment_set.end();
// Loop over the segment pairs
for (; it != end ; ++it) {
if (!it->first.is_degenerate()) {
Vector<UInt> segment_connectivity(2);
segment_connectivity(0) = result_mesh.getNbNodes();
segment_connectivity(1) = result_mesh.getNbNodes() + 1;
connectivity.push_back(segment_connectivity);
// Copy nodes
Vector<Real> source(dim), target(dim);
for (UInt j = 0 ; j < dim ; j++) {
source(j) = it->first.source()[j];
target(j) = it->first.target()[j];
}
nodes.push_back(source);
nodes.push_back(target);
// Copy associated element info
if (valid_elemental_data) {
associated_element->push_back(Element(type, it->second));
associated_physical_name->push_back(current_physical_name);
}
}
}
AKANTU_DEBUG_OUT();
}
template<UInt dim, ElementType type>
void MeshSegmentIntersector<dim, type>:: computeMeshQueryIntersectionPoint(const K::Segment_3 & query,
UInt nb_old_nodes) {
AKANTU_DEBUG_ERROR("The method: computeMeshQueryIntersectionPoint has not been implemented in class MeshSegmentIntersector!");
}
template<UInt dim, ElementType type>
void MeshSegmentIntersector<dim, type>::buildResultFromQueryList(const std::list<K::Segment_3> & query_list) {
AKANTU_DEBUG_IN();
this->computeIntersectionQueryList(query_list);
AKANTU_DEBUG_OUT();
}
template<UInt dim, ElementType type>
void MeshSegmentIntersector<dim, type>::computeSegments(const std::list<result_type> & intersections,
std::set<pair_type, segmentPairsLess> & segments,
const K::Segment_3 & query) {
AKANTU_DEBUG_IN();
/*
* Number of intersections = 0 means
*
* - query is completely outside mesh
* - query is completely inside primitive
*
* We try to determine the case and still construct the segment list
*/
if (intersections.size() == 0) {
// We look at all the primitives intersected by two rays
// If there is one primitive in common, then query is inside
// that primitive
K::Ray_3 ray1(query.source(), query.target());
K::Ray_3 ray2(query.target(), query.source());
std::set<UInt> ray1_results, ray2_results;
this->factory.getTree().all_intersected_primitives(ray1, std::inserter(ray1_results, ray1_results.begin()));
this->factory.getTree().all_intersected_primitives(ray2, std::inserter(ray2_results, ray2_results.begin()));
bool inside_primitive = false;
UInt primitive_id = 0;
std::set<UInt>::iterator
ray2_it = ray2_results.begin(),
ray2_end = ray2_results.end();
// Test if first list contains an element of second list
for (; ray2_it != ray2_end && !inside_primitive ; ++ray2_it) {
if (ray1_results.find(*ray2_it) != ray1_results.end()) {
inside_primitive = true;
primitive_id = *ray2_it;
}
}
if (inside_primitive) {
segments.insert(std::make_pair(query, primitive_id));
}
}
else {
typename std::list<result_type>::const_iterator
it = intersections.begin(),
end = intersections.end();
for(; it != end ; ++it) {
UInt el = (*it)->second;
// Result of intersection is a segment
if (const K::Segment_3 * segment = boost::get<K::Segment_3>(&((*it)->first))) {
// Check if the segment was alread created
segments.insert(std::make_pair(*segment, el));
}
// Result of intersection is a point
else if (const K::Point_3 * point = boost::get<K::Point_3>(&((*it)->first))) {
// We only want to treat points differently if we're in 3D with Tetra4 elements
// This should be optimized by compilator
if (dim == 3 && type == _tetrahedron_4) {
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
TreeTypeHelper<Triangle<K>, K>::container_type facets;
const Array<Real> & nodes = this->mesh.getNodes();
Array<UInt>::const_vector_iterator
connectivity_vec = this->mesh.getConnectivity(type).begin(nb_nodes_per_element);
const Vector<UInt> & el_connectivity = connectivity_vec[el];
Matrix<Real> node_coordinates(dim, nb_nodes_per_element);
for (UInt i = 0 ; i < nb_nodes_per_element ; i++)
for (UInt j = 0 ; j < dim ; j++)
node_coordinates(j, i) = nodes(el_connectivity(i), j);
this->factory.addPrimitive(node_coordinates, el, facets);
// Local tree
TreeTypeHelper<Triangle<K>, K>::tree * local_tree =
new TreeTypeHelper<Triangle<K>, K>::tree(facets.begin(), facets.end());
// Compute local intersections (with current element)
std::list<result_type> local_intersections;
local_tree->all_intersections(query, std::back_inserter(local_intersections));
bool out_point_found = false;
typename std::list<result_type>::const_iterator
local_it = local_intersections.begin(),
local_end = local_intersections.end();
for (; local_it != local_end ; ++local_it) {
if (const K::Point_3 * local_point = boost::get<K::Point_3>(&((*local_it)->first))) {
if (!comparePoints(*point, *local_point)) {
K::Segment_3 seg(*point, *local_point);
segments.insert(std::make_pair(seg, el));
out_point_found = true;
}
}
}
if (!out_point_found) {
TreeTypeHelper<Triangle<K>, K>::point_type
a(node_coordinates(0, 0), node_coordinates(1, 0), node_coordinates(2, 0)),
b(node_coordinates(0, 1), node_coordinates(1, 1), node_coordinates(2, 1)),
c(node_coordinates(0, 2), node_coordinates(1, 2), node_coordinates(2, 2)),
d(node_coordinates(0, 3), node_coordinates(1, 3), node_coordinates(2, 3));
K::Tetrahedron_3 tetra(a, b, c, d);
const K::Point_3 * inside_point = NULL;
if (tetra.has_on_bounded_side(query.source()) && !tetra.has_on_boundary(query.source()))
inside_point = &query.source();
else if (tetra.has_on_bounded_side(query.target()) && !tetra.has_on_boundary(query.target()))
inside_point = &query.target();
if (inside_point) {
K::Segment_3 seg(*inside_point, *point);
segments.insert(std::make_pair(seg, el));
}
}
delete local_tree;
}
}
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
#endif // __AKANTU_MESH_SEGMENT_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/mesh_sphere_intersector.hh b/src/geometry/mesh_sphere_intersector.hh
index 487d1827e..d996c6ff0 100644
--- a/src/geometry/mesh_sphere_intersector.hh
+++ b/src/geometry/mesh_sphere_intersector.hh
@@ -1,101 +1,105 @@
/**
- * @file mesh_sphere_intersector.hh
+ * @file mesh_sphere_intersector.hh
*
- * @author Clement Roux-Langlois <clement.roux@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@eplf.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Wed Jun 10 2015
+ * @date creation: Tue Jun 23 2015
+ * @date last modification: Thu Jan 14 2016
*
- * @brief Computation of mesh intersection with sphere(s)
+ * @brief Computation of mesh intersection with sphere(s)
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
#define __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
#include "aka_common.hh"
#include "mesh_geom_intersector.hh"
#include "mesh_geom_common.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/// Here, we know what kernel we have to use
typedef Spherical SK;
template<UInt dim, ElementType type>
class MeshSphereIntersector : public MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK> {
/// Parent class type
typedef MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK> parent_type;
/// Result of intersection function type
typedef typename IntersectionTypeHelper<TreeTypeHelper< Triangle<K>, K>, K::Segment_3>::intersection_type result_type;
/// Pair of intersection points and element id
typedef std::pair<SK::Circular_arc_point_3, UInt> pair_type;
public:
/// Construct from mesh
explicit MeshSphereIntersector(Mesh & mesh);
/// Destructor
virtual ~MeshSphereIntersector();
public:
/// Construct the primitive tree object
virtual void constructData(GhostType ghost_type = _not_ghost);
/**
* @brief Computes the intersection of the mesh with a sphere
*
* @param query (sphere) to compute the intersections with the mesh
*/
virtual void computeIntersectionQuery(const SK::Sphere_3 & query){
AKANTU_DEBUG_ERROR("This function is not implemented for spheres (It was to generic and has been replaced by computeMeshQueryIntersectionPoint");
}
/// 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 is set to the number of intersection nodes per element: 2 in 2D and 4 in 3D
virtual void computeMeshQueryIntersectionPoint(const SK::Sphere_3 & query, UInt nb_old_nodes);
/// Build the IGFEM mesh
virtual void buildResultFromQueryList(const std::list<SK::Sphere_3> & query){
AKANTU_DEBUG_ERROR("This function is no longer implemented to split geometrical operations and dedicated result construction");
}
/// Set the tolerance
void setToleranceIntersectionOnNode(UInt tol) {
this->tol_intersection_on_node = tol;
}
protected:
/// tolerance for which the intersection is considered on the mesh node (relative to the segment lenght)
Real tol_intersection_on_node;
};
__END_AKANTU__
#include "mesh_sphere_intersector_tmpl.hh"
#endif // __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_sphere_intersector_tmpl.hh b/src/geometry/mesh_sphere_intersector_tmpl.hh
index 72ad9f6fa..44a5120e0 100644
--- a/src/geometry/mesh_sphere_intersector_tmpl.hh
+++ b/src/geometry/mesh_sphere_intersector_tmpl.hh
@@ -1,193 +1,196 @@
/**
- * @file mesh_sphere_intersector_tmpl.hh
+ * @file mesh_sphere_intersector_tmpl.hh
*
- * @author Clément Roux-Langlois <clement.roux@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Wed june 10 2015
- * @date last modification: Wed June 17 2015
+ * @date creation: Tue Jun 23 2015
+ * @date last modification: Thu Jan 14 2016
*
- * @brief Computation of mesh intersection with spheres
+ * @brief Computation of mesh intersection with spheres
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
#define __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
#include "tree_type_helper.hh"
#include "mesh_sphere_intersector.hh"
#include "static_communicator.hh"
__BEGIN_AKANTU__
template<UInt dim, ElementType type>
MeshSphereIntersector<dim, type>::MeshSphereIntersector(Mesh & mesh):
parent_type(mesh),
tol_intersection_on_node(1e-10)
{
#if defined(AKANTU_IGFEM)
if( (type == _triangle_3) || (type == _igfem_triangle_4) || (type == _igfem_triangle_5) ){
const_cast<UInt &>(this->nb_seg_by_el) = 3;
} else {
AKANTU_DEBUG_ERROR("Not ready for mesh type " << type);
}
#else
if( (type != _triangle_3) )
AKANTU_DEBUG_ERROR("Not ready for mesh type " << type);
#endif
// initialize the intersection pointsss array with the spatial dimension
this->intersection_points = new Array<Real>(0,dim);
// A maximum is set to the number of intersection nodes per element to limit the size of new_node_per_elem: 2 in 2D and 4 in 3D
this->new_node_per_elem = new Array<UInt>(0, 1 + 4 * (dim-1));
}
template<UInt dim, ElementType type>
MeshSphereIntersector<dim, type>::~MeshSphereIntersector() {
delete this->new_node_per_elem;
delete this->intersection_points;
}
template<UInt dim, ElementType type>
void MeshSphereIntersector<dim, type>::constructData(GhostType ghost_type) {
this->new_node_per_elem->resize(this->mesh.getNbElement(type, ghost_type));
this->new_node_per_elem->clear();
MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK>::constructData(ghost_type);
}
template<UInt dim, ElementType type>
void MeshSphereIntersector<dim, type>:: computeMeshQueryIntersectionPoint(const SK::Sphere_3 & query,
UInt nb_old_nodes) {
/// function to replace computeIntersectionQuery in a more generic geometry module version
// The newNodeEvent is not send from this method who only compute the intersection points
AKANTU_DEBUG_IN();
Array<Real> & nodes = this->mesh.getNodes();
UInt nb_node = nodes.getSize() + this->intersection_points->getSize();
// Tolerance for proximity checks should be defined by user
Real global_tolerance = Math::getTolerance();
Math::setTolerance(tol_intersection_on_node);
typedef boost::variant<pair_type> sk_inter_res;
TreeTypeHelper<Line_arc<Spherical>, Spherical>::const_iterator
it = this->factory.getPrimitiveList().begin(),
end= this->factory.getPrimitiveList().end();
for (; it != end ; ++it) { // loop on the primitives (segments)
std::list<sk_inter_res> s_results;
CGAL::intersection(*it, query, std::back_inserter(s_results));
if (s_results.size() == 1) { // just one point
if (pair_type * pair = boost::get<pair_type>(&s_results.front())) {
if (pair->second == 1) { // not a point tangent to the sphere
// the intersection point written as a vector
Vector<Real> new_node(dim, 0.0);
Cartesian::Point_3 point(CGAL::to_double(pair->first.x()),
CGAL::to_double(pair->first.y()),
CGAL::to_double(pair->first.z()));
for (UInt i = 0 ; i < dim ; i++) {
new_node(i) = point[i];
}
/// boolean to decide wheter intersection point is on a standard node of the mesh or not
bool is_on_mesh = false;
/// boolean to decide if this intersection point has been already computed for a neighbor element
bool is_new = true;
/// check if intersection point has already been computed
UInt n = nb_old_nodes;
// check if we already compute this intersection and add it as a node for a neighboor element of another type
Array<Real>::vector_iterator existing_node = nodes.begin(dim);
for (; n < nodes.getSize() ; ++n) {// loop on the nodes from nb_old_nodes
if (Math::are_vector_equal(dim, new_node.storage(), existing_node[n].storage())) {
is_new = false;
break;
}
}
if(is_new){
Array<Real>::vector_iterator intersection_points_it = this->intersection_points->begin(dim);
Array<Real>::vector_iterator intersection_points_end = this->intersection_points->end(dim);
for (; intersection_points_it != intersection_points_end ; ++intersection_points_it, ++n) {
if (Math::are_vector_equal(dim, new_node.storage(), intersection_points_it->storage())) {
is_new = false;
break;
}
}
}
// get the initial and final points of the primitive (segment) and write them as vectors
Cartesian::Point_3 source_cgal(CGAL::to_double(it->source().x()),
CGAL::to_double(it->source().y()),
CGAL::to_double(it->source().z()));
Cartesian::Point_3 target_cgal(CGAL::to_double(it->target().x()),
CGAL::to_double(it->target().y()),
CGAL::to_double(it->target().z()));
Vector<Real> source(dim), target(dim);
for (UInt i = 0 ; i < dim ; i++) {
source(i) = source_cgal[i];
target(i) = target_cgal[i];
}
// Check if we are close from a node of the primitive (segment)
if (Math::are_vector_equal(dim, source.storage(), new_node.storage()) ||
Math::are_vector_equal(dim, target.storage(), new_node.storage())) {
is_on_mesh = true;
is_new = false;
}
if (is_new) {// if the intersection point is a new one add it to the list
this->intersection_points->push_back(new_node);
nb_node++;
}
// deduce the element id
UInt element_id = it->id();
// fill the new_node_per_elem array
if (!is_on_mesh) { // if the node is not on a mesh node
UInt & nb_new_nodes_per_el = (*this->new_node_per_elem)(element_id, 0);
nb_new_nodes_per_el += 1;
AKANTU_DEBUG_ASSERT(2 * nb_new_nodes_per_el < this->new_node_per_elem->getNbComponent(),
"You might have to interface crossing the same material");
(*this->new_node_per_elem)(element_id, (2 * nb_new_nodes_per_el) - 1) = n;
(*this->new_node_per_elem)(element_id, 2 * nb_new_nodes_per_el) = it->segId();
}
}
}
}
}
Math::setTolerance(global_tolerance);
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
#endif // __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/tree_type_helper.hh b/src/geometry/tree_type_helper.hh
index 1f5132501..3e6646664 100644
--- a/src/geometry/tree_type_helper.hh
+++ b/src/geometry/tree_type_helper.hh
@@ -1,111 +1,111 @@
/**
* @file tree_type_helper.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Fri Feb 27 2015
- * @date last modification: Thu Mar 5 2015
+ * @date creation: Fri Jan 04 2013
+ * @date last modification: Thu Jan 14 2016
*
* @brief Converts element types of a mesh to CGAL primitive types
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TREE_TYPE_HELPER_HH__
#define __AKANTU_TREE_TYPE_HELPER_HH__
#include "aka_common.hh"
#include "line_arc.hh"
#include "triangle.hh"
#include "tetrahedron.hh"
#include "aabb_primitive.hh"
#include "mesh_geom_common.hh"
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_tree.h>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/// Replacement class for algorithm that can't use the AABB tree types
template<typename iterator>
struct VoidTree {
VoidTree(const iterator & begin, const iterator & end) {}
};
/// Helper class used to ease the use of CGAL AABB tree algorithm
template<class Primitive, class Kernel>
struct TreeTypeHelper {
static const bool is_valid = false;
typedef Primitive primitive_type;
typedef typename std::list<primitive_type> container_type;
typedef typename container_type::iterator iterator;
typedef typename container_type::const_iterator const_iterator;
typedef typename CGAL::Point_3<Kernel> point_type;
typedef VoidTree<iterator> tree;
};
/// Helper class used to ease the use of intersections
template<class TTHelper, class Query>
struct IntersectionTypeHelper;
/**
* Macro used to specialize TreeTypeHelper
* @param my_primitive associated primitive type
* @param my_query query_type
* @param my_kernel kernel type
*/
#define TREE_TYPE_HELPER_MACRO(my_primitive, my_query, my_kernel) \
template<> \
struct TreeTypeHelper<my_primitive<my_kernel>, my_kernel> { \
static const bool is_valid = true; \
typedef my_primitive<my_kernel> primitive_type; \
typedef my_primitive##_primitive aabb_primitive_type; \
typedef CGAL::Point_3<my_kernel> point_type; \
\
typedef std::list<primitive_type> container_type; \
typedef container_type::iterator iterator; \
typedef CGAL::AABB_traits<my_kernel, aabb_primitive_type> aabb_traits_type; \
typedef CGAL::AABB_tree<aabb_traits_type> tree; \
typedef tree::Primitive_id id_type; \
}; \
\
template<> \
struct IntersectionTypeHelper<TreeTypeHelper<my_primitive<my_kernel>, my_kernel>, my_query> { \
typedef boost::optional< \
TreeTypeHelper<my_primitive<my_kernel>, my_kernel>::tree::Intersection_and_primitive_id<my_query>::Type \
> intersection_type; \
}
TREE_TYPE_HELPER_MACRO(Triangle, Cartesian::Segment_3, Cartesian);
//TREE_TYPE_HELPER_MACRO(Line_arc, Spherical::Sphere_3, Spherical);
#undef TREE_TYPE_HELPER_MACRO
__END_AKANTU__
#endif // __AKANTU_TREE_TYPE_HELPER_HH__
diff --git a/src/io/dumper/dumpable.cc b/src/io/dumper/dumpable.cc
index 749e6a151..fca99bf0c 100644
--- a/src/io/dumper/dumpable.cc
+++ b/src/io/dumper/dumpable.cc
@@ -1,310 +1,311 @@
/**
* @file dumpable.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Sep 05 2014
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Wed Nov 11 2015
*
* @brief Implementation of the dumpable interface
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dumpable.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
#include <io_helper.hh>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
Dumpable::Dumpable() : default_dumper("") {
}
/* -------------------------------------------------------------------------- */
Dumpable::~Dumpable() {
DumperMap::iterator it = dumpers.begin();
DumperMap::iterator end = dumpers.end();
for (; it != end; ++it){
delete it->second;
}
}
/* -------------------------------------------------------------------------- */
void Dumpable::registerExternalDumper(DumperIOHelper & dumper,
const std::string & dumper_name,
const bool is_default) {
this->dumpers[dumper_name] = &dumper;
if (is_default)
this->default_dumper = dumper_name;
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpMesh(const Mesh & mesh, UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
this->addDumpMeshToDumper(this->default_dumper,
mesh,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpMeshToDumper(const std::string & dumper_name,
const Mesh & mesh, UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerMesh(mesh,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
this->addDumpFilteredMeshToDumper(this->default_dumper,
mesh,
elements_filter,
nodes_filter,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFilteredMeshToDumper(const std::string & dumper_name,
const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerFilteredMesh(mesh,
elements_filter,
nodes_filter,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpField(const std::string & field_id) {
this->addDumpFieldToDumper(this->default_dumper, field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id) {
AKANTU_DEBUG_TO_IMPLEMENT();
};
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldExternal(const std::string & field_id,
dumper::Field * field) {
this->addDumpFieldExternalToDumper(this->default_dumper, field_id, field);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerField(field_id, field);
}
/* -------------------------------------------------------------------------- */
void Dumpable::removeDumpField(const std::string & field_id) {
this->removeDumpFieldFromDumper(this->default_dumper, field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::removeDumpFieldFromDumper(const std::string & dumper_name,
const std::string & field_id) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.unRegisterField(field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldVector(const std::string & field_id) {
this->addDumpFieldVectorToDumper(this->default_dumper, field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldTensor(const std::string & field_id) {
this->addDumpFieldTensorToDumper(this->default_dumper, field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldTensorToDumper(const std::string & dumper_name,
const std::string & field_id) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
void Dumpable::setDirectory(const std::string & directory) {
this->setDirectoryToDumper(this->default_dumper, directory);
};
/* -------------------------------------------------------------------------- */
void Dumpable::setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.setDirectory(directory);
}
/* -------------------------------------------------------------------------- */
void Dumpable::setBaseName(const std::string & basename) {
this->setBaseNameToDumper(this->default_dumper, basename);
}
/* -------------------------------------------------------------------------- */
void Dumpable::setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.setBaseName(basename);
}
/* -------------------------------------------------------------------------- */
void Dumpable::setTimeStepToDumper(Real time_step) {
this->setTimeStepToDumper(this->default_dumper, time_step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::setTimeStepToDumper(const std::string & dumper_name,
Real time_step) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.setTimeStep(time_step);
};
/* -------------------------------------------------------------------------- */
void Dumpable::setTextModeToDumper(const std::string & dumper_name) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.getDumper().setMode(iohelper::TEXT);
};
/* -------------------------------------------------------------------------- */
void Dumpable::setTextModeToDumper() {
DumperIOHelper & dumper = this->getDumper(this->default_dumper);
dumper.getDumper().setMode(iohelper::TEXT);
};
/* -------------------------------------------------------------------------- */
void Dumpable::dump(const std::string & dumper_name) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.dump();
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump() {
this->dump(this->default_dumper);
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump(const std::string & dumper_name, UInt step) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.dump(step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump(UInt step) {
this->dump(this->default_dumper, step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump(const std::string & dumper_name, Real time, UInt step) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.dump(time, step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump(Real time, UInt step) {
this->dump(this->default_dumper, time, step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::internalAddDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerField(field_id, field);
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Dumpable::getDumper() {
return this->getDumper(this->default_dumper);
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Dumpable::getDumper(const std::string & dumper_name) {
DumperMap::iterator it = this->dumpers.find(dumper_name);
DumperMap::iterator end = this->dumpers.end();
if (it == end)
AKANTU_EXCEPTION("Dumper " << dumper_name << "has not been registered, yet.");
return *(it->second);
}
/* -------------------------------------------------------------------------- */
std::string Dumpable::getDefaultDumperName() const {
return this->default_dumper;
}
__END_AKANTU__
#endif
diff --git a/src/io/dumper/dumpable.hh b/src/io/dumper/dumpable.hh
index 6051ed11d..064ab647b 100644
--- a/src/io/dumper/dumpable.hh
+++ b/src/io/dumper/dumpable.hh
@@ -1,48 +1,49 @@
/**
* @file dumpable.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Oct 26 2012
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Tue Jan 06 2015
*
* @brief Interface for object who wants to dump themselves
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "element_type_map.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPABLE_HH__
#define __AKANTU_DUMPABLE_HH__
#ifdef AKANTU_USE_IOHELPER
# include "dumpable_iohelper.hh"
#else
# include "dumpable_dummy.hh"
#endif //AKANTU_USE_IOHELPER
#endif /* __AKANTU_DUMPABLE_HH__ */
diff --git a/src/io/dumper/dumpable_dummy.hh b/src/io/dumper/dumpable_dummy.hh
index ec8018af5..d955275af 100644
--- a/src/io/dumper/dumpable_dummy.hh
+++ b/src/io/dumper/dumpable_dummy.hh
@@ -1,251 +1,252 @@
/**
- * @file dumpable.hh
+ * @file dumpable_dummy.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Oct 26 2012
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Fri Aug 21 2015
*
* @brief Interface for object who wants to dump themselves
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPABLE_DUMMY_HH__
#define __AKANTU_DUMPABLE_DUMMY_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused"
namespace dumper {
class Field;
}
class DumperIOHelper;
class Mesh;
/* -------------------------------------------------------------------------- */
class Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Dumpable() {};
virtual ~Dumpable() { };
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
template<class T>
inline void registerDumper(const std::string & dumper_name,
const std::string & file_name = "",
const bool is_default = false) { }
void registerExternalDumper(DumperIOHelper * dumper,
const std::string & dumper_name,
const bool is_default = false) { }
void addDumpMesh(const Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) {
}
void addDumpMeshToDumper(const std::string & dumper_name,
const Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) {
}
void addDumpFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) {
}
void addDumpFilteredMeshToDumper(const std::string & dumper_name,
const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) {
}
virtual void addDumpField(const std::string & field_id){
AKANTU_DEBUG_TO_IMPLEMENT();
}
virtual void addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id){
AKANTU_DEBUG_TO_IMPLEMENT();
}
virtual void addDumpFieldExternal(const std::string & field_id,
dumper::Field * field) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
virtual void addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
template<typename T>
void addDumpFieldExternal(const std::string & field_id,
const Array<T> & field) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
template<typename T>
void addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
const Array<T> & field) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
template<typename T>
void addDumpFieldExternal(const std::string & field_id,
const ElementTypeMapArray<T> & field,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
template<typename T>
void addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
const ElementTypeMapArray<T> & field,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void removeDumpField(const std::string & field_id) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void removeDumpFieldFromDumper(const std::string & dumper_name,
const std::string & field_id) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void setDirectory(const std::string & directory) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void setBaseName(const std::string & basename) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void setTextModeToDumper(const std::string & dumper_name){
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void setTextModeToDumper(){
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void dump() {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void dump(const std::string & dumper_name) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void dump(UInt step) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void dump(const std::string & dumper_name,
UInt step) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void dump(Real current_time,
UInt step) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
void dump(const std::string & dumper_name,
Real current_time,
UInt step) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
protected:
void internalAddDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field) {
AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
protected:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
DumperIOHelper & getDumper() {
AKANTU_DEBUG_ERROR("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
DumperIOHelper & getDumper(const std::string & dumper_name){
AKANTU_DEBUG_ERROR("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
template<class T>
T & getDumper(const std::string & dumper_name) {
AKANTU_DEBUG_ERROR("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
std::string getDefaultDumperName() {
AKANTU_DEBUG_ERROR("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
#pragma GCC diagnostic pop
__END_AKANTU__
#endif /* __AKANTU_DUMPABLE_DUMMY_HH__ */
diff --git a/src/io/dumper/dumpable_inline_impl.hh b/src/io/dumper/dumpable_inline_impl.hh
index b58a7b53a..47e8b27f6 100644
--- a/src/io/dumper/dumpable_inline_impl.hh
+++ b/src/io/dumper/dumpable_inline_impl.hh
@@ -1,147 +1,147 @@
/**
* @file dumpable_inline_impl.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Nov 15 2015
*
* @brief Implementation of the Dumpable class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPABLE_INLINE_IMPL_HH__
#define __AKANTU_DUMPABLE_INLINE_IMPL_HH__
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
#include "dumper_elemental_field.hh"
#include "dumper_nodal_field.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<class T>
inline void Dumpable::registerDumper(const std::string & dumper_name,
const std::string & file_name,
const bool is_default) {
if (this->dumpers.find(dumper_name) != this->dumpers.end()){
AKANTU_DEBUG_INFO("Dumper " + dumper_name + "is already registered.");
}
std::string name = file_name;
if (name == "")
name = dumper_name;
this->dumpers[dumper_name] = new T(name);
if (is_default)
this->default_dumper = dumper_name;
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Dumpable::addDumpFieldExternal(const std::string & field_id,
const Array<T> & field) {
this->addDumpFieldExternalToDumper<T>(this->default_dumper,
field_id,
field);
};
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Dumpable::addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
const Array<T> & field) {
dumper::Field * field_cont = new dumper::NodalField<T>(field);
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerField(field_id, field_cont);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Dumpable::addDumpFieldExternal(const std::string & field_id,
const ElementTypeMapArray<T> & field,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
this->addDumpFieldExternalToDumper(this->default_dumper,
field_id,
field,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Dumpable::addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
const ElementTypeMapArray<T> & field,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
dumper::Field * field_cont;
#if defined(AKANTU_IGFEM)
if (element_kind == _ek_igfem) {
field_cont = new dumper::IGFEMElementalField<T>(field,
spatial_dimension,
ghost_type,
element_kind);
} else
#endif
field_cont = new dumper::ElementalField<T>(field,
spatial_dimension,
ghost_type,
element_kind);
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerField(field_id, field_cont);
}
/* -------------------------------------------------------------------------- */
template<class T>
inline T & Dumpable::getDumper(const std::string & dumper_name) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
try {
T & templated_dumper = dynamic_cast<T & >(dumper);
return templated_dumper;
}
catch (...) {
AKANTU_EXCEPTION("Dumper " << dumper_name << " is not of type: "
<< debug::demangle(typeid(T).name()));
}
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif
#endif /* __AKANTU_DUMPABLE_INLINE_IMPL_HH__ */
diff --git a/src/io/dumper/dumpable_iohelper.hh b/src/io/dumper/dumpable_iohelper.hh
index b08f104cd..3d7330154 100644
--- a/src/io/dumper/dumpable_iohelper.hh
+++ b/src/io/dumper/dumpable_iohelper.hh
@@ -1,195 +1,195 @@
/**
- * @file dumpable.hh
+ * @file dumpable_iohelper.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Oct 26 2012
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Tue Jan 06 2015
+ * @date last modification: Thu Nov 19 2015
*
* @brief Interface for object who wants to dump themselves
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPABLE_IOHELPER_HH__
#define __AKANTU_DUMPABLE_IOHELPER_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_iohelper.hh"
#include <set>
__BEGIN_AKANTU__
class Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Dumpable();
virtual ~Dumpable();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// create a new dumper (of templated type T) and register it under
/// dumper_name. file_name is used for construction of T. is default states if
/// this dumper is the default dumper.
template<class T>
inline void registerDumper(const std::string & dumper_name,
const std::string & file_name = "",
const bool is_default = false);
/// register an externally created dumper
void registerExternalDumper(DumperIOHelper & dumper,
const std::string & dumper_name,
const bool is_default = false);
/// register a mesh to the default dumper
void addDumpMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a mesh to the default identified by its name
void addDumpMeshToDumper(const std::string & dumper_name,
const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a filtered mesh as the default dumper
void addDumpFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a filtered mesh and provides a name
void addDumpFilteredMeshToDumper(const std::string & dumper_name,
const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// to implement
virtual void addDumpField(const std::string & field_id);
/// to implement
virtual void addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id);
/// add a field
virtual void addDumpFieldExternal(const std::string & field_id,
dumper::Field * field);
virtual void addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field);
template<typename T>
inline void addDumpFieldExternal(const std::string & field_id,
const Array<T> & field);
template<typename T>
inline void addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
const Array<T> & field);
template<typename T>
inline void addDumpFieldExternal(const std::string & field_id,
const ElementTypeMapArray<T> & field,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
template<typename T>
inline void addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
const ElementTypeMapArray<T> & field,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
void removeDumpField(const std::string & field_id);
void removeDumpFieldFromDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldVector(const std::string & field_id);
virtual void addDumpFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldTensor(const std::string & field_id);
virtual void addDumpFieldTensorToDumper(const std::string & dumper_name,
const std::string & field_id);
void setDirectory(const std::string & directory);
void setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory);
void setBaseName(const std::string & basename);
void setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename);
void setTimeStepToDumper(Real time_step);
void setTimeStepToDumper(const std::string & dumper_name,
Real time_step);
void setTextModeToDumper(const std::string & dumper_name);
void setTextModeToDumper();
virtual void dump();
virtual void dump(UInt step);
virtual void dump(Real time, UInt step);
virtual void dump(const std::string & dumper_name);
virtual void dump(const std::string & dumper_name, UInt step);
virtual void dump(const std::string & dumper_name, Real time, UInt step);
public:
void internalAddDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
DumperIOHelper & getDumper();
DumperIOHelper & getDumper(const std::string & dumper_name);
template<class T> T & getDumper(const std::string & dumper_name);
std::string getDefaultDumperName() const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
typedef std::map<std::string, DumperIOHelper *> DumperMap;
typedef std::set<std::string> DumperSet;
DumperMap dumpers;
std::string default_dumper;
};
__END_AKANTU__
#endif /* __AKANTU_DUMPABLE_IOHELPER_HH__ */
diff --git a/src/io/dumper/dumper_compute.hh b/src/io/dumper/dumper_compute.hh
index 13f1dc4e9..aa5bd5595 100644
--- a/src/io/dumper/dumper_compute.hh
+++ b/src/io/dumper/dumper_compute.hh
@@ -1,272 +1,272 @@
/**
* @file dumper_compute.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Sun Nov 15 2015
*
* @brief Field that map a function to another field
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_COMPUTE_HH__
#define __AKANTU_DUMPER_COMPUTE_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "dumper_iohelper.hh"
#include "dumper_type_traits.hh"
#include "dumper_field.hh"
#include <io_helper.hh>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
class ComputeFunctorInterface {
public:
virtual ~ComputeFunctorInterface(){};
virtual UInt getDim() = 0;
virtual UInt getNbComponent(UInt old_nb_comp) = 0;
};
/* -------------------------------------------------------------------------- */
template <typename return_type>
class ComputeFunctorOutput : public ComputeFunctorInterface {
public:
ComputeFunctorOutput(){};
virtual ~ComputeFunctorOutput(){};
};
/* -------------------------------------------------------------------------- */
template <typename input_type,typename return_type>
class ComputeFunctor : public ComputeFunctorOutput<return_type> {
public:
ComputeFunctor(){};
virtual ~ComputeFunctor(){};
virtual return_type func(const input_type & d, Element global_index) = 0;
};
/* -------------------------------------------------------------------------- */
template <typename SubFieldCompute, typename _return_type>
class FieldCompute : public Field {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef typename SubFieldCompute::iterator sub_iterator;
typedef typename SubFieldCompute::types sub_types;
typedef typename sub_types::return_type sub_return_type;
typedef _return_type return_type;
typedef typename sub_types::data_type data_type;
typedef TypeTraits<data_type, return_type, ElementTypeMapArray<data_type> > types;
class iterator {
public:
iterator(const sub_iterator & it, ComputeFunctor<sub_return_type,return_type> & func)
: it(it), func(func) {}
bool operator!=(const iterator & it)const { return it.it != this->it; }
iterator operator++() { ++this->it; return *this; }
UInt currentGlobalIndex(){
return this->it.currentGlobalIndex();
}
return_type operator*() {
return func.func(*it,it.getCurrentElement());
}
Element getCurrentElement(){
return this->it.getCurrentElement();
}
UInt element_type() { return this->it.element_type(); }
protected:
sub_iterator it;
ComputeFunctor<sub_return_type,return_type> & func;
};
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
FieldCompute(SubFieldCompute & cont, ComputeFunctorInterface & func)
:sub_field(cont),func(dynamic_cast<ComputeFunctor<sub_return_type,return_type> &>(func)){
this->checkHomogeneity();
};
virtual void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) {
dumper.addElemDataField(id, *this);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
iterator begin() { return iterator(sub_field.begin(), func); }
iterator end () { return iterator(sub_field.end(), func); }
UInt getDim() {
return func.getDim();
}
UInt size() {
throw;
// return Functor::size();
return 0;
}
virtual void checkHomogeneity(){this->homogeneous = true;};
iohelper::DataType getDataType() { return iohelper::getDataType<data_type>(); }
/// get the number of components of the hosted field
virtual ElementTypeMap<UInt> getNbComponents(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined){
ElementTypeMap<UInt> nb_components;
const ElementTypeMap<UInt> & old_nb_components =
this->sub_field.getNbComponents(dim,ghost_type,kind);
ElementTypeMap<UInt>::type_iterator tit = old_nb_components.firstType(dim,ghost_type,kind);
ElementTypeMap<UInt>::type_iterator end = old_nb_components.lastType(dim,ghost_type,kind);
while (tit != end){
UInt nb_comp = old_nb_components(*tit,ghost_type);
nb_components(*tit,ghost_type) = func.getNbComponent(nb_comp);
++tit;
}
return nb_components;
};
/// for connection to a FieldCompute
inline virtual Field * connect(FieldComputeProxy & proxy);
/// for connection to a FieldCompute
virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
SubFieldCompute & sub_field;
ComputeFunctor<sub_return_type,return_type> & func;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class FieldComputeProxy {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
FieldComputeProxy(ComputeFunctorInterface & func):func(func){};
inline static Field * createFieldCompute(Field * field,
ComputeFunctorInterface & func){
FieldComputeProxy compute_proxy(func);
return field->connect(compute_proxy);
}
template <typename T>
Field * connectToField(T * ptr){
if (dynamic_cast<ComputeFunctorOutput<Vector<Real> > *>(&func)){
return this->connectToFunctor<Vector<Real> >(ptr);
}
else if (dynamic_cast<ComputeFunctorOutput<Vector<UInt> > *>(&func)){
return this->connectToFunctor<Vector<UInt> >(ptr);
}
else if (dynamic_cast<ComputeFunctorOutput<Matrix<UInt> > *>(&func)){
return this->connectToFunctor<Matrix<UInt> >(ptr);
}
else if (dynamic_cast<ComputeFunctorOutput<Matrix<Real> > *>(&func)){
return this->connectToFunctor<Matrix<Real> >(ptr);
}
else throw;
}
template <typename output, typename T>
Field * connectToFunctor(T * ptr){
FieldCompute<T,output> * functor_ptr = new FieldCompute<T,output>(*ptr,func);
return functor_ptr;
}
template <typename output, typename SubFieldCompute,
typename return_type1, typename return_type2>
Field * connectToFunctor(FieldCompute<FieldCompute<SubFieldCompute,return_type1>,
return_type2> * ptr){
throw; // return new FieldCompute<T,output>(*ptr,func);
return NULL;
}
template <typename output, typename SubFieldCompute,
typename return_type1,typename return_type2,
typename return_type3,typename return_type4>
Field * connectToFunctor(FieldCompute<
FieldCompute<
FieldCompute<
FieldCompute<SubFieldCompute,return_type1>,
return_type2>,
return_type3>,
return_type4> * ptr){
throw; // return new FieldCompute<T,output>(*ptr,func);
return NULL;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
ComputeFunctorInterface & func;
};
/* -------------------------------------------------------------------------- */
/// for connection to a FieldCompute
template <typename SubFieldCompute, typename return_type>
inline Field * FieldCompute<SubFieldCompute,return_type>
::connect(FieldComputeProxy & proxy){
return proxy.connectToField(this);
}
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_COMPUTE_HH__ */
diff --git a/src/io/dumper/dumper_element_iterator.hh b/src/io/dumper/dumper_element_iterator.hh
index d71c1064d..d28dd853f 100644
--- a/src/io/dumper/dumper_element_iterator.hh
+++ b/src/io/dumper/dumper_element_iterator.hh
@@ -1,193 +1,193 @@
/**
* @file dumper_element_iterator.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Wed Sep 03 2014
+ * @date last modification: Fri May 15 2015
*
* @brief Iterators for elemental fields
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_ELEMENT_ITERATOR_HH__
#define __AKANTU_DUMPER_ELEMENT_ITERATOR_HH__
/* -------------------------------------------------------------------------- */
#include "element.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template<class types, template <class> class final_iterator>
class element_iterator {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef typename types::it_type it_type;
typedef typename types::field_type field_type;
typedef typename types::array_type array_type;
typedef typename types::array_iterator array_iterator;
typedef final_iterator<types> iterator;
public:
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
element_iterator(const field_type & field,
const typename field_type::type_iterator & t_it,
const typename field_type::type_iterator & t_it_end,
const array_iterator & array_it,
const array_iterator & array_it_end,
const GhostType ghost_type = _not_ghost)
: field(field),
tit(t_it),
tit_end(t_it_end),
array_it(array_it),
array_it_end(array_it_end),
ghost_type(ghost_type) {
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
bool operator!=(const iterator & it) const {
return (ghost_type != it.ghost_type)
|| (tit != it.tit || (array_it != it.array_it));
}
iterator & operator++() {
++array_it;
while(array_it == array_it_end && tit != tit_end) {
++tit;
if(tit != tit_end) {
const array_type & vect = field(*tit, ghost_type);
UInt _nb_data_per_elem = getNbDataPerElem(*tit);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.getSize() * nb_component) / _nb_data_per_elem;
array_it = vect.begin_reinterpret(_nb_data_per_elem,size);
array_it_end = vect.end_reinterpret (_nb_data_per_elem,size);
}
}
return *(static_cast<iterator *>(this));
};
ElementType getType() { return *tit; }
UInt element_type() { return getIOHelperType(*tit); }
Element getCurrentElement(){
return Element(*tit,array_it.getCurrentIndex());
}
UInt getNbDataPerElem(const ElementType & type) const {
if (!nb_data_per_elem.exists(type, ghost_type))
return field(type,ghost_type).getNbComponent();
return nb_data_per_elem(type,ghost_type);
}
void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data){
this->nb_data_per_elem = nb_data;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the field to iterate on
const field_type & field;
/// field iterator
typename field_type::type_iterator tit;
/// field iterator end
typename field_type::type_iterator tit_end;
/// array iterator
array_iterator array_it;
/// internal iterator end
array_iterator array_it_end;
/// ghost type identification
const GhostType ghost_type;
/// number of data per element
ElementTypeMap<UInt> nb_data_per_elem;
};
/* -------------------------------------------------------------------------- */
template<typename types>
class elemental_field_iterator
: public element_iterator<types, elemental_field_iterator> {
public:
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
typedef element_iterator<types, ::akantu::dumper::elemental_field_iterator> parent;
typedef typename types::it_type it_type;
typedef typename types::return_type return_type;
typedef typename types::field_type field_type;
typedef typename types::array_iterator array_iterator;
public:
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
elemental_field_iterator(const field_type & field,
const typename field_type::type_iterator & t_it,
const typename field_type::type_iterator & t_it_end,
const array_iterator & array_it,
const array_iterator & array_it_end,
const GhostType ghost_type = _not_ghost) :
parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) { }
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
return_type operator*(){
return *this->array_it;
}
private:
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
/* -------------------------------------------------------------------------- */
#endif /* __AKANTU_DUMPER_ELEMENT_ITERATOR_HH__ */
diff --git a/src/io/dumper/dumper_element_partition.hh b/src/io/dumper/dumper_element_partition.hh
index 3c4ed6f3d..a4eb05d66 100644
--- a/src/io/dumper/dumper_element_partition.hh
+++ b/src/io/dumper/dumper_element_partition.hh
@@ -1,123 +1,124 @@
/**
* @file dumper_element_partition.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Tue Jul 14 2015
*
* @brief ElementPartition field
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
#ifdef AKANTU_IGFEM
# include "dumper_igfem_element_partition.hh"
#endif
/* -------------------------------------------------------------------------- */
template<class types>
class element_partition_field_iterator
: public element_iterator<types, element_partition_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef element_iterator<types, dumper::element_partition_field_iterator> parent;
typedef typename types::return_type return_type;
typedef typename types::array_iterator array_iterator;
typedef typename types::field_type field_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
element_partition_field_iterator(const field_type & field,
const typename field_type::type_iterator & t_it,
const typename field_type::type_iterator & t_it_end,
const array_iterator & array_it,
const array_iterator & array_it_end,
const GhostType ghost_type = _not_ghost) :
parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) {
prank = StaticCommunicator::getStaticCommunicator().whoAmI();
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
return_type operator*() {
return return_type(1, prank);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
UInt prank;
};
/* -------------------------------------------------------------------------- */
template<bool filtered = false>
class ElementPartitionField :
public GenericElementalField<SingleType<UInt,Vector,filtered>,
element_partition_field_iterator> {
public:
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
typedef SingleType<UInt,Vector,filtered> types;
typedef element_partition_field_iterator<types> iterator;
typedef GenericElementalField<types,element_partition_field_iterator> parent;
typedef typename types::field_type field_type;
public:
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
ElementPartitionField(const field_type & field,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind element_kind = _ek_not_defined) :
parent(field, spatial_dimension, ghost_type, element_kind) {
this->homogeneous = true;
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
UInt getDim() { return 1; }
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
diff --git a/src/io/dumper/dumper_elemental_field.hh b/src/io/dumper/dumper_elemental_field.hh
index 19c83c414..cec891358 100644
--- a/src/io/dumper/dumper_elemental_field.hh
+++ b/src/io/dumper/dumper_elemental_field.hh
@@ -1,79 +1,80 @@
/**
* @file dumper_elemental_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Mon Aug 17 2015
*
* @brief description of elemental fields
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
#ifndef __AKANTU_DUMPER_ELEMENTAL_FIELD_HH__
#define __AKANTU_DUMPER_ELEMENTAL_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "static_communicator.hh"
#include "dumper_field.hh"
#include "dumper_generic_elemental_field.hh"
#ifdef AKANTU_IGFEM
# include "dumper_igfem_elemental_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template<typename T, template <class> class ret = Vector,bool filtered = false>
class ElementalField
: public GenericElementalField<SingleType<T,ret,filtered>,
elemental_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef SingleType<T,ret,filtered> types;
typedef typename types::field_type field_type;
typedef elemental_field_iterator<types> iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ElementalField(const field_type & field,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind element_kind = _ek_not_defined) :
GenericElementalField<types,elemental_field_iterator>(field,
spatial_dimension,
ghost_type,
element_kind) { }
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_ELEMENTAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_field.hh b/src/io/dumper/dumper_field.hh
index 1661275c0..12db7c388 100644
--- a/src/io/dumper/dumper_field.hh
+++ b/src/io/dumper/dumper_field.hh
@@ -1,123 +1,124 @@
/**
* @file dumper_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Wed Sep 03 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief Common interface for fields
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_FIELD_HH__
#define __AKANTU_DUMPER_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_iohelper.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
class FieldComputeProxy;
class FieldComputeBaseInterface;
class ComputeFunctorInterface;
class HomogenizerProxy;
/* -------------------------------------------------------------------------- */
/// Field interface
class Field {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Field(): homogeneous(false) {}
virtual ~Field() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
#ifdef AKANTU_USE_IOHELPER
/// register this to the provided dumper
virtual void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) = 0;
#endif
/// set the number of data per item (used for elements fields at the moment)
virtual void setNbData(UInt nb_data){AKANTU_DEBUG_TO_IMPLEMENT();};
/// set the number of data per elem (used for elements fields at the moment)
virtual void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data){AKANTU_DEBUG_TO_IMPLEMENT();};
/// set the number of data per elem (used for elements fields at the moment)
virtual void setNbDataPerElem(UInt nb_data){AKANTU_DEBUG_TO_IMPLEMENT();};
/// get the number of components of the hosted field
virtual ElementTypeMap<UInt> getNbComponents(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined){throw;};
/// for connection to a FieldCompute
inline virtual Field * connect(FieldComputeProxy & proxy){throw;};
/// for connection to a FieldCompute
inline virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy){throw;};
/// check if the same quantity of data for all element types
virtual void checkHomogeneity() = 0;
/// return the dumper name
std::string getGroupName(){return group_name;};
/// return the id of the field
std::string getID(){return field_id;};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// return the flag to know if the field is homogeneous/contiguous
virtual bool isHomogeneous() { return homogeneous; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the flag to know if it is homogeneous
bool homogeneous;
/// the name of the group it was associated to
std::string group_name;
/// the name of the dumper it was associated to
std::string field_id;
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_filtered_connectivity.hh b/src/io/dumper/dumper_filtered_connectivity.hh
index 8d1fc51df..9f4f313e7 100644
--- a/src/io/dumper/dumper_filtered_connectivity.hh
+++ b/src/io/dumper/dumper_filtered_connectivity.hh
@@ -1,150 +1,151 @@
/**
* @file dumper_filtered_connectivity.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Mon Aug 17 2015
*
* @brief FilteredConnectivities field
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "dumper_generic_elemental_field.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <class types>
class filtered_connectivity_field_iterator
: public element_iterator<types, filtered_connectivity_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef element_iterator<types, dumper::filtered_connectivity_field_iterator> parent;
typedef typename types::return_type return_type;
typedef typename types::field_type field_type;
typedef typename types::array_iterator array_iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
filtered_connectivity_field_iterator(const field_type & field,
const typename field_type::type_iterator & t_it,
const typename field_type::type_iterator & t_it_end,
const array_iterator & array_it,
const array_iterator & array_it_end,
const GhostType ghost_type = _not_ghost) :
parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) { }
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
return_type operator*(){
const Vector<UInt> & old_connect = *this->array_it;
Vector<UInt> new_connect(old_connect.size());
Array<UInt>::const_iterator<UInt> nodes_begin = nodal_filter->begin();
Array<UInt>::const_iterator<UInt> nodes_end = nodal_filter->end();
for(UInt i(0); i<old_connect.size(); ++i) {
Array<UInt>::const_iterator<UInt> new_id =
std::find(nodes_begin, nodes_end, old_connect(i));
if(new_id == nodes_end) AKANTU_EXCEPTION("Node not found in the filter!");
new_connect(i) = new_id - nodes_begin;
}
return new_connect;
}
void setNodalFilter(const Array<UInt> & new_nodal_filter) {
nodal_filter = &new_nodal_filter;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
const Array<UInt> * nodal_filter;
};
/* -------------------------------------------------------------------------- */
class FilteredConnectivityField :
public GenericElementalField<SingleType<UInt,Vector,true>,
filtered_connectivity_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef SingleType<UInt,Vector,true> types;
typedef filtered_connectivity_field_iterator<types> iterator;
typedef types::field_type field_type;
typedef GenericElementalField<types,filtered_connectivity_field_iterator> parent;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
FilteredConnectivityField(const field_type & field,
const Array<UInt> & nodal_filter,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind element_kind = _ek_not_defined) :
parent(field, spatial_dimension, ghost_type, element_kind),
nodal_filter(nodal_filter) { }
~FilteredConnectivityField() {
// since the field is created in registerFilteredMesh it is destroyed here
delete const_cast<field_type *>(&this->field);
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
iterator begin() {
iterator it = parent::begin();
it.setNodalFilter(nodal_filter);
return it;
}
iterator end() {
iterator it = parent::end();
it.setNodalFilter(nodal_filter);
return it;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
const Array<UInt> & nodal_filter;
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
/* -------------------------------------------------------------------------- */
diff --git a/src/io/dumper/dumper_generic_elemental_field.hh b/src/io/dumper/dumper_generic_elemental_field.hh
index 6f35c558e..52074e644 100644
--- a/src/io/dumper/dumper_generic_elemental_field.hh
+++ b/src/io/dumper/dumper_generic_elemental_field.hh
@@ -1,224 +1,224 @@
/**
* @file dumper_generic_elemental_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Mon Sep 21 2015
*
* @brief Generic interface for elemental fields
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__
#define __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_field.hh"
#include "element_type_map_filter.hh"
#include "dumper_element_iterator.hh"
#include "dumper_homogenizing_field.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <class _types, template <class> class iterator_type>
class GenericElementalField : public Field {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
// check dumper_type_traits.hh for additional information over these types
typedef _types types;
typedef typename types::data_type data_type;
typedef typename types::it_type it_type;
typedef typename types::field_type field_type;
typedef typename types::array_type array_type;
typedef typename types::array_iterator array_iterator;
typedef typename field_type::type_iterator field_type_iterator;
typedef iterator_type<types> iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
GenericElementalField(const field_type & field,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind element_kind = _ek_not_defined)
: field(field), spatial_dimension(spatial_dimension),
ghost_type(ghost_type), element_kind(element_kind) {
this->checkHomogeneity();
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get the number of components of the hosted field
virtual ElementTypeMap<UInt>
getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) {
return this->field.getNbComponents(dim, ghost_type, kind);
};
/// return the size of the contained data: i.e. the number of elements ?
virtual UInt size() {
checkHomogeneity();
return this->nb_total_element;
}
/// return the iohelper datatype to be dumped
iohelper::DataType getDataType() {
return iohelper::getDataType<data_type>();
}
protected:
/// return the number of entries per element
UInt getNbDataPerElem(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
if (!nb_data_per_elem.exists(type, ghost_type))
return field(type, ghost_type).getNbComponent();
return nb_data_per_elem(type, this->ghost_type);
}
/// check if the same quantity of data for all element types
virtual void checkHomogeneity();
public:
virtual void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) {
dumper.addElemDataField(id, *this);
};
/// for connection to a FieldCompute
inline virtual Field * connect(FieldComputeProxy & proxy) {
return proxy.connectToField(this);
}
/// for connection to a Homogenizer
inline virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy) {
return proxy.connectToField(this);
};
virtual iterator begin() {
field_type_iterator tit;
field_type_iterator end;
/// type iterators on the elemental field
tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
this->element_kind);
end = this->field.lastType(this->spatial_dimension, this->ghost_type,
this->element_kind);
/// skip all types without data
ElementType type = *tit;
for (; tit != end && this->field(*tit, this->ghost_type).getSize() == 0;
++tit) {
}
type = *tit;
if (tit == end)
return this->end();
/// getting information for the field of the given type
const array_type & vect = this->field(type, this->ghost_type);
UInt nb_data_per_elem = this->getNbDataPerElem(type);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.getSize() * nb_component) / nb_data_per_elem;
/// define element-wise iterator
array_iterator it = vect.begin_reinterpret(nb_data_per_elem, size);
array_iterator it_end = vect.end_reinterpret(nb_data_per_elem, size);
/// define data iterator
iterator rit =
iterator(this->field, tit, end, it, it_end, this->ghost_type);
rit.setNbDataPerElem(this->nb_data_per_elem);
return rit;
}
virtual iterator end() {
field_type_iterator tit;
field_type_iterator end;
tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
this->element_kind);
end = this->field.lastType(this->spatial_dimension, this->ghost_type,
this->element_kind);
ElementType type = *tit;
for (; tit != end; ++tit)
type = *tit;
const array_type & vect = this->field(type, this->ghost_type);
UInt nb_data = this->getNbDataPerElem(type);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.getSize() * nb_component) / nb_data;
array_iterator it = vect.end_reinterpret(nb_data, size);
iterator rit = iterator(this->field, end, end, it, it, this->ghost_type);
rit.setNbDataPerElem(this->nb_data_per_elem);
return rit;
}
virtual UInt getDim() {
if (this->homogeneous) {
field_type_iterator tit = this->field.firstType(
this->spatial_dimension, this->ghost_type, this->element_kind);
return this->getNbDataPerElem(*tit);
}
throw;
return 0;
}
void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data) {
nb_data_per_elem = nb_data;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the ElementTypeMapArray embedded in the field
const field_type & field;
/// total number of elements
UInt nb_total_element;
/// the spatial dimension of the problem
UInt spatial_dimension;
/// whether this is a ghost field or not (for type selection)
GhostType ghost_type;
/// The element kind to operate on
ElementKind element_kind;
/// The number of data per element type
ElementTypeMap<UInt> nb_data_per_elem;
};
/* -------------------------------------------------------------------------- */
#include "dumper_generic_elemental_field_tmpl.hh"
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__ __END_AKANTU__
#endif /* __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_generic_elemental_field_tmpl.hh b/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
index 9ef53f79a..ee491bd10 100644
--- a/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
+++ b/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
@@ -1,67 +1,67 @@
/**
* @file dumper_generic_elemental_field_tmpl.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the template functions of the ElementalField
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
template<class types, template <class> class iterator>
void GenericElementalField<types,iterator>::checkHomogeneity() {
typedef typename field_type::type_iterator field_type_iterator;
typedef typename field_type::array_type array_type;
field_type_iterator tit;
field_type_iterator end;
tit = field.firstType(spatial_dimension, ghost_type, element_kind);
end = field.lastType(spatial_dimension, ghost_type, element_kind);
this->nb_total_element = 0;
UInt nb_comp = 0;
bool homogen = true;
if(tit != end) {
nb_comp = this->field(*tit, ghost_type).getNbComponent();
for(;tit != end; ++tit) {
const array_type & vect = this->field(*tit, ghost_type);
UInt nb_element = vect.getSize();
UInt nb_comp_cur = vect.getNbComponent();
if(homogen && nb_comp != nb_comp_cur) homogen = false;
this->nb_total_element += nb_element;
// this->nb_data_per_elem(*tit,this->ghost_type) = nb_comp_cur;
}
if(!homogen) nb_comp = 0;
}
this->homogeneous = homogen;
}
/* -------------------------------------------------------------------------- */
diff --git a/src/io/dumper/dumper_homogenizing_field.hh b/src/io/dumper/dumper_homogenizing_field.hh
index 9317030f0..a65026a93 100644
--- a/src/io/dumper/dumper_homogenizing_field.hh
+++ b/src/io/dumper/dumper_homogenizing_field.hh
@@ -1,227 +1,227 @@
/**
* @file dumper_homogenizing_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Tue Jul 14 2015
*
* @brief description of field homogenizing field
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_HOMOGENIZING_FIELD_HH__
#define __AKANTU_DUMPER_HOMOGENIZING_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_compute.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <typename type>
inline type typeConverter(const type & input,
Vector<typename type::value_type> & res,UInt nb_data){
throw;
return input;
}
/* -------------------------------------------------------------------------- */
template <typename type>
inline Matrix<type> typeConverter(const Matrix<type> & input,
Vector<type> & res,UInt nb_data){
Matrix<type> tmp(res.storage(),input.rows(),nb_data/input.rows());
Matrix<type> tmp2(tmp,true);
return tmp2;
}
/* -------------------------------------------------------------------------- */
template <typename type>
inline Vector<type> typeConverter(const Vector<type> & input,
Vector<type> & res,UInt nb_data){
return res;
}
/* -------------------------------------------------------------------------- */
template <typename type>
class AvgHomogenizingFunctor : public ComputeFunctor<type,type> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
typedef typename type::value_type value_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
AvgHomogenizingFunctor(ElementTypeMap<UInt> & nb_datas){
ElementTypeMap<UInt>::type_iterator tit = nb_datas.firstType();
ElementTypeMap<UInt>::type_iterator end = nb_datas.lastType();
nb_data = nb_datas(*tit);
for (;tit != end; ++tit) if (nb_data != nb_datas(*tit)) throw;
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
virtual type func(const type & d, Element global_index){
Vector<value_type> res(this->nb_data);
if (d.size() % this->nb_data) throw;
UInt nb_to_average = d.size()/this->nb_data;
value_type * ptr = d.storage();
for (UInt i = 0; i < nb_to_average; ++i) {
Vector<value_type> tmp(ptr,this->nb_data);
res += tmp;
ptr += this->nb_data;
}
res /= nb_to_average;
return typeConverter(d,res,this->nb_data);
};
UInt getDim(){return nb_data;};
UInt getNbComponent(UInt old_nb_comp){
throw;
};
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// The size of data: i.e. the size of the vector to be returned
UInt nb_data;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class HomogenizerProxy {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
HomogenizerProxy(){};
public:
inline static ComputeFunctorInterface * createHomogenizer(Field & field);
template <typename T>
inline ComputeFunctorInterface * connectToField(T * field){
ElementTypeMap<UInt> nb_components = field->getNbComponents();
typedef typename T::types::return_type ret_type;
return this->instantiateHomogenizer<ret_type>(nb_components);
}
template <typename ret_type>
inline ComputeFunctorInterface *
instantiateHomogenizer(ElementTypeMap<UInt> & nb_components);
};
/* -------------------------------------------------------------------------- */
template <typename ret_type>
inline ComputeFunctorInterface * HomogenizerProxy
::instantiateHomogenizer(ElementTypeMap<UInt> & nb_components){
typedef dumper::AvgHomogenizingFunctor<ret_type> Homogenizer;
Homogenizer * foo = new Homogenizer(nb_components);
return foo;
}
template <>
inline ComputeFunctorInterface * HomogenizerProxy
::instantiateHomogenizer<Vector<iohelper::ElemType> > (ElementTypeMap<UInt> & nb_components){
throw;
return NULL;
}
/* -------------------------------------------------------------------------- */
/// for connection to a FieldCompute
template <typename SubFieldCompute, typename return_type>
inline ComputeFunctorInterface * FieldCompute<SubFieldCompute,return_type>
::connect(HomogenizerProxy & proxy){
return proxy.connectToField(this);
}
/* -------------------------------------------------------------------------- */
inline ComputeFunctorInterface * HomogenizerProxy::createHomogenizer(Field & field){
HomogenizerProxy homogenizer_proxy;
return field.connect(homogenizer_proxy);
}
/* -------------------------------------------------------------------------- */
// inline ComputeFunctorInterface & createHomogenizer(Field & field){
// HomogenizerProxy::createHomogenizer(field);
// throw;
// ComputeFunctorInterface * ptr = NULL;
// return *ptr;
// }
// /* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_HOMOGENIZING_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_internal_material_field.hh b/src/io/dumper/dumper_internal_material_field.hh
index 7ed413a85..84c68f24f 100644
--- a/src/io/dumper/dumper_internal_material_field.hh
+++ b/src/io/dumper/dumper_internal_material_field.hh
@@ -1,78 +1,78 @@
/**
* @file dumper_internal_material_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Sep 17 2015
*
* @brief description of material internal field
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
-
#ifndef __AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH__
#define __AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_quadrature_point_iterator.hh"
#ifdef AKANTU_IGFEM
# include "dumper_igfem_material_internal_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template<typename T, bool filtered = false>
class InternalMaterialField
: public GenericElementalField<SingleType<T,Vector,filtered>,
quadrature_point_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef SingleType<T,Vector,filtered> types;
typedef GenericElementalField<types,quadrature_point_iterator> parent;
typedef typename types::field_type field_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
InternalMaterialField(const field_type & field,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind element_kind = _ek_not_defined) :
parent(field, spatial_dimension, ghost_type, element_kind){}
};
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_iohelper.cc b/src/io/dumper/dumper_iohelper.cc
index 435266e13..7e431f426 100644
--- a/src/io/dumper/dumper_iohelper.cc
+++ b/src/io/dumper/dumper_iohelper.cc
@@ -1,294 +1,295 @@
/**
* @file dumper_iohelper.cc
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Oct 26 2012
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Thu Sep 17 2015
*
* @brief implementation of DumperIOHelper
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <io_helper.hh>
#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<UInt>(mesh.getConnectivities(),
spatial_dimension,
ghost_type,
element_kind));
registerField("positions",
new dumper::NodalField<Real>(mesh.getNodes()));
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::registerFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
ElementTypeMapArrayFilter<UInt> * f_connectivities =
new ElementTypeMapArrayFilter<UInt>(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<Real,true>(
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 <ElementType type>
iohelper::ElemType getIOHelperType() {
AKANTU_DEBUG_TO_IMPLEMENT();
return iohelper::MAX_ELEM_TYPE;
}
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<type>();
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_IOHELPER_TYPE);
#undef GET_IOHELPER_TYPE
return ioh_type;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/io/dumper/dumper_iohelper.hh b/src/io/dumper/dumper_iohelper.hh
index 78eaaf8a1..c905a9925 100644
--- a/src/io/dumper/dumper_iohelper.hh
+++ b/src/io/dumper/dumper_iohelper.hh
@@ -1,156 +1,157 @@
/**
* @file dumper_iohelper.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Dana Christen <dana.christen@epfl.ch>
*
* @date creation: Fri Oct 26 2012
- * @date last modification: Wed Sep 03 2014
+ * @date last modification: Fri Apr 17 2015
*
* @brief Define the akantu dumper interface for IOhelper dumpers
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_types.hh"
#include "aka_array.hh"
#include "element_type_map.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPER_IOHELPER_HH__
#define __AKANTU_DUMPER_IOHELPER_HH__
/* -------------------------------------------------------------------------- */
namespace iohelper {
class Dumper;
}
__BEGIN_AKANTU__
UInt getIOHelperType(ElementType type);
namespace dumper {
class Field;
class VariableBase;
}
class Mesh;
class DumperIOHelper {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DumperIOHelper();
virtual ~DumperIOHelper();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// register a given Mesh for the current dumper
virtual void registerMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a filtered Mesh (provided filter lists) for the current dumper
virtual void registerFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a Field object identified by name and provided by pointer
void registerField(const std::string & field_id, dumper::Field * field);
/// remove the Field identified by name from managed fields
void unRegisterField(const std::string & field_id);
/// register a VariableBase object identified by name and provided by pointer
void registerVariable(const std::string & variable_id, dumper::VariableBase * variable);
/// remove a VariableBase identified by name from managed fields
void unRegisterVariable(const std::string & variable_id);
/// request dump: this calls IOHelper dump routine
virtual void dump();
/// request dump: this first set the current step and then calls IOHelper dump routine
virtual void dump(UInt step);
/// request dump: this first set the current step and current time and then calls IOHelper dump routine
virtual void dump(Real current_time, UInt step);
/// set the parallel context for IOHeper
virtual void setParallelContext(bool is_parallel);
/// set the directory where to generate the dumped files
virtual void setDirectory(const std::string & directory);
/// set the base name (needed by most IOHelper dumpers)
virtual void setBaseName(const std::string & basename);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// direct access to the iohelper::Dumper object
AKANTU_GET_MACRO(Dumper, *dumper, iohelper::Dumper &)
/// set the timestep of the iohelper::Dumper
void setTimeStep(Real time_step);
public:
/* ------------------------------------------------------------------------ */
/* Variable wrapper */
template<typename T, bool is_scal = is_scalar<T>::value>
class Variable;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// internal iohelper::Dumper
iohelper::Dumper * dumper;
typedef std::map<std::string, dumper::Field *> Fields;
typedef std::map<std::string, dumper::VariableBase *> Variables;
/// list of registered fields to dump
Fields fields;
Variables variables;
/// dump counter
UInt count;
/// directory name
std::string directory;
/// filename prefix
std::string filename;
/// is time tracking activated in the dumper
bool time_activated;
};
__END_AKANTU__
#endif /* __AKANTU_DUMPER_IOHELPER_HH__ */
diff --git a/src/io/dumper/dumper_material_padders.hh b/src/io/dumper/dumper_material_padders.hh
index 1ffecd8da..da94344ec 100644
--- a/src/io/dumper/dumper_material_padders.hh
+++ b/src/io/dumper/dumper_material_padders.hh
@@ -1,290 +1,291 @@
/**
* @file dumper_material_padders.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Fri Mar 27 2015
*
* @brief Material padders for plane stress/ plane strain
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_MATERIAL_PADDERS_HH__
#define __AKANTU_DUMPER_MATERIAL_PADDERS_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_padding_helper.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
class MaterialFunctor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialFunctor(const SolidMechanicsModel & model) :
model(model),
material_index(model.getMaterialByElement()),
spatial_dimension(model.getSpatialDimension()){}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
/// return the material from the global element index
const Material & getMaterialFromGlobalIndex(Element global_index){
UInt index = global_index.getIndex();
UInt material_id = material_index(global_index.getType())(index);
const Material & material = model.getMaterial(material_id);
return material;
}
/// return the type of the element from global index
ElementType getElementTypeFromGlobalIndex(Element global_index){
return global_index.getType();
}
protected:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// all material padders probably need access to solid mechanics model
const SolidMechanicsModel & model;
/// they also need an access to the map from global ids to material id and local ids
const ElementTypeMapArray<UInt> & material_index;
/// the number of data per element
const ElementTypeMapArray<UInt> nb_data_per_element;
UInt spatial_dimension;
};
/* -------------------------------------------------------------------------- */
template<class T, class R>
class MaterialPadder : public MaterialFunctor, public PadderGeneric<Vector<T>, R > {
public:
MaterialPadder(const SolidMechanicsModel & model) :
MaterialFunctor(model) {}
};
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
class StressPadder : public MaterialPadder<Real, Matrix<Real> > {
public:
StressPadder(const SolidMechanicsModel & model) :
MaterialPadder<Real, Matrix<Real> >(model){
this->setPadding(3,3);
}
inline Matrix<Real> func(const Vector<Real> & in, Element global_element_id){
UInt nrows = spatial_dimension;
UInt ncols = in.size() / nrows;
UInt nb_data = in.size() / (nrows*nrows);
Matrix<Real> stress = this->pad(in, nrows, ncols, nb_data);
const Material & material = this->getMaterialFromGlobalIndex(global_element_id);
bool plane_strain = true;
if(spatial_dimension == 2)
plane_strain = !material.getParam<bool>("Plane_Stress");
if(plane_strain) {
Real nu = material.getParam<Real>("nu");
for (UInt d = 0; d < nb_data; ++d) {
stress(2, 2 + 3*d) = nu * (stress(0, 0 + 3*d) + stress(1, 1 + 3*d));
}
}
return stress;
}
UInt getDim(){return 9;};
UInt getNbComponent(UInt old_nb_comp){
return this->getDim();
};
};
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
class StrainPadder : public MaterialFunctor, public PadderGeneric< Matrix<Real>, Matrix<Real> > {
public:
StrainPadder(const SolidMechanicsModel & model) :
MaterialFunctor(model) {
this->setPadding(3,3);
}
inline Matrix<Real> func(const Matrix<Real> & in, Element global_element_id){
UInt nrows = spatial_dimension;
UInt nb_data = in.size() / (nrows*nrows);
Matrix<Real> strain = this->pad(in, nb_data);
const Material & material = this->getMaterialFromGlobalIndex(global_element_id);
bool plane_stress = material.getParam<bool>("Plane_Stress");
if(plane_stress) {
Real nu = material.getParam<Real>("nu");
for (UInt d = 0; d < nb_data; ++d) {
strain(2, 2 + 3*d) = nu / (nu - 1) * (strain(0, 0 + 3*d) + strain(1, 1 + 3*d));
}
}
return strain;
}
UInt getDim(){return 9;};
UInt getNbComponent(UInt old_nb_comp){
return this->getDim();
};
};
/* -------------------------------------------------------------------------- */
template <bool green_strain>
class ComputeStrain : public MaterialFunctor, public ComputeFunctor<Vector<Real>, Matrix<Real> > {
public:
ComputeStrain(const SolidMechanicsModel & model) : MaterialFunctor(model) { }
inline Matrix<Real> func(const Vector<Real> & in, Element global_element_id){
UInt nrows = spatial_dimension;
UInt ncols = in.size() / nrows;
UInt nb_data = in.size() / (nrows*nrows);
Matrix<Real> ret_all_strain(nrows, ncols);
Tensor3<Real> all_grad_u(in.storage(), nrows, nrows, nb_data);
Tensor3<Real> all_strain(ret_all_strain.storage(), nrows, nrows, nb_data);
for (UInt d = 0; d < nb_data; ++d) {
Matrix<Real> grad_u = all_grad_u(d);
Matrix<Real> strain = all_strain(d);
if (spatial_dimension == 2) {
if (green_strain)
Material::gradUToGreenStrain<2>(grad_u, strain);
else
Material::gradUToEpsilon<2>(grad_u, strain);
}
else if (spatial_dimension == 3) {
if (green_strain)
Material::gradUToGreenStrain<3>(grad_u, strain);
else
Material::gradUToEpsilon<3>(grad_u, strain);
}
}
return ret_all_strain;
}
UInt getDim() { return spatial_dimension*spatial_dimension; };
UInt getNbComponent(UInt old_nb_comp){
return this->getDim();
};
};
/* -------------------------------------------------------------------------- */
template <bool green_strain>
class ComputePrincipalStrain : public MaterialFunctor, public ComputeFunctor<Vector<Real>,
Matrix<Real> > {
public:
ComputePrincipalStrain(const SolidMechanicsModel & model) : MaterialFunctor(model) { }
inline Matrix<Real> func(const Vector<Real> & in, Element global_element_id){
UInt nrows = spatial_dimension;
UInt nb_data = in.size() / (nrows*nrows);
Matrix<Real> ret_all_strain(nrows, nb_data);
Tensor3<Real> all_grad_u(in.storage(), nrows, nrows, nb_data);
Matrix<Real> strain(nrows, nrows);
for (UInt d = 0; d < nb_data; ++d) {
Matrix<Real> grad_u = all_grad_u(d);
if (spatial_dimension == 2) {
if (green_strain)
Material::gradUToGreenStrain<2>(grad_u, strain);
else
Material::gradUToEpsilon<2>(grad_u, strain);
}
else if (spatial_dimension == 3) {
if (green_strain)
Material::gradUToGreenStrain<3>(grad_u, strain);
else
Material::gradUToEpsilon<3>(grad_u, strain);
}
Vector<Real> principal_strain(ret_all_strain(d));
strain.eig(principal_strain);
}
return ret_all_strain;
}
UInt getDim() { return spatial_dimension; };
UInt getNbComponent(UInt old_nb_comp){
return this->getDim();
};
};
/* -------------------------------------------------------------------------- */
class ComputeVonMisesStress : public MaterialFunctor,
public ComputeFunctor<Vector<Real>, Vector<Real> > {
public:
ComputeVonMisesStress(const SolidMechanicsModel & model) : MaterialFunctor(model) { }
inline Vector<Real> func(const Vector<Real> & in, Element global_element_id){
UInt nrows = spatial_dimension;
UInt nb_data = in.size() / (nrows*nrows);
Vector<Real> von_mises_stress(nb_data);
Matrix<Real> deviatoric_stress(3, 3);
for (UInt d = 0; d < nb_data; ++d) {
Matrix<Real> cauchy_stress(in.storage() + d * nrows*nrows, nrows, nrows);
von_mises_stress(d) = Material::stressToVonMises(cauchy_stress);
}
return von_mises_stress;
}
UInt getDim() { return 1; };
UInt getNbComponent(UInt old_nb_comp){
return this->getDim();
};
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_MATERIAL_PADDERS_HH__ */
diff --git a/src/io/dumper/dumper_nodal_field.hh b/src/io/dumper/dumper_nodal_field.hh
index bd9c2de11..86ce33f9d 100644
--- a/src/io/dumper/dumper_nodal_field.hh
+++ b/src/io/dumper/dumper_nodal_field.hh
@@ -1,239 +1,240 @@
/**
* @file dumper_nodal_field.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Oct 26 2012
+ * @date last modification: Tue Jan 06 2015
*
* @brief Description of nodal fields
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
#ifndef __AKANTU_DUMPER_NODAL_FIELD_HH__
#define __AKANTU_DUMPER_NODAL_FIELD_HH__
#include "dumper_field.hh"
#include <io_helper.hh>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
// This represents a iohelper compatible field
template<typename T, bool filtered = false,
class Container = Array<T>, class Filter = Array<UInt> >
class NodalField;
/* -------------------------------------------------------------------------- */
template<typename T, class Container, class Filter>
class NodalField<T, false, Container, Filter> : public dumper::Field {
public:
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
/// associated iterator with any nodal field (non filetered)
class iterator : public iohelper::iterator< T, iterator, Vector<T> > {
public:
iterator(T * vect, UInt offset, UInt n, UInt stride,
__attribute__ ((unused)) const UInt * filter = NULL) :
internal_it(vect), offset(offset), n(n), stride(stride) {}
bool operator!=(const iterator & it) const { return internal_it != it.internal_it; }
iterator & operator++() { internal_it += offset; return *this; };
Vector<T> operator* (){ return Vector<T>(internal_it + stride, n); };
private:
T * internal_it;
UInt offset, n, stride;
};
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
NodalField(const Container & field, UInt n = 0, UInt stride = 0,
__attribute__ ((unused)) const Filter * filter = NULL) :
field(field), n(n), stride(stride), padding(0) {
AKANTU_DEBUG_ASSERT(filter == NULL, "Filter passed to unfiltered NodalField!");
if(n == 0) { this->n = field.getNbComponent() - stride; }
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
virtual void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) {
dumper.addNodeDataField(id, *this);
}
inline iterator begin() {
return iterator(field.storage(), field.getNbComponent(), n, stride);
}
inline iterator end () {
return iterator(field.storage() + field.getNbComponent()*field.getSize(),
field.getNbComponent(), n, stride);
}
bool isHomogeneous() { return true; }
void checkHomogeneity() { this->homogeneous = true; }
virtual UInt getDim() {
if(this->padding) return this->padding;
else return n;
}
void setPadding(UInt padding){this->padding = padding;}
UInt size() { return field.getSize(); }
iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
const Container & field;
UInt n, stride;
UInt padding;
};
/* -------------------------------------------------------------------------- */
template<typename T, class Container, class Filter>
class NodalField<T, true, Container, Filter> : public dumper::Field {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
class iterator : public iohelper::iterator< T, iterator, Vector<T> > {
public:
iterator(T * const vect, UInt _offset, UInt _n,
UInt _stride, const UInt * filter) :
internal_it(vect), offset(_offset), n(_n), stride(_stride),
filter(filter) {}
bool operator!=(const iterator & it) const {
return filter != it.filter;
}
iterator & operator++() {
++filter;
return *this;
}
Vector<T> operator* () {
return Vector<T>(internal_it + *(filter)*offset + stride, n);
}
private:
T * const internal_it;
UInt offset, n, stride;
const UInt * filter;
};
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
NodalField(const Container & _field,
UInt _n = 0, UInt _stride = 0,
const Filter * filter = NULL)
: field(_field), n(_n), stride(_stride), filter(filter), padding(0) {
AKANTU_DEBUG_ASSERT(this->filter != NULL,
"No filter passed to filtered NodalField!");
AKANTU_DEBUG_ASSERT(this->filter->getNbComponent()==1,
"Multi-component filter given to NodalField ("
<< this->filter->getNbComponent()
<< " components detected, sould be 1");
if(n == 0) {
this->n = field.getNbComponent() - stride;
}
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
virtual void registerToDumper(const std::string & id, iohelper::Dumper & dumper) {
dumper.addNodeDataField(id, *this);
}
inline iterator begin() {
return iterator(field.storage(), field.getNbComponent(),
n, stride, filter->storage());
}
inline iterator end() {
return iterator(field.storage(), field.getNbComponent(),
n, stride, filter->storage()+filter->getSize());
}
bool isHomogeneous() {
return true;
}
void checkHomogeneity() { this->homogeneous = true; }
virtual UInt getDim() {
if(this->padding) return this->padding;
else return n;
}
void setPadding(UInt padding){this->padding = padding;}
UInt size() {
return filter->getSize();
}
iohelper::DataType getDataType() {
return iohelper::getDataType<T>();
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
const Container & field;
UInt n, stride;
const Filter * filter;
UInt padding;
};
__END_AKANTU_DUMPER__
__END_AKANTU__
/* -------------------------------------------------------------------------- */
#endif /* __AKANTU_DUMPER_NODAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_padding_helper.hh b/src/io/dumper/dumper_padding_helper.hh
index fb8e3522d..7c99fed0e 100644
--- a/src/io/dumper/dumper_padding_helper.hh
+++ b/src/io/dumper/dumper_padding_helper.hh
@@ -1,146 +1,147 @@
/**
* @file dumper_padding_helper.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Padding helper for field iterators
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_PADDING_HELPER_HH__
#define __AKANTU_DUMPER_PADDING_HELPER_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_compute.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
class PadderInterface {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PadderInterface(){
padding_m = 0;
padding_n = 0;
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void setPadding(UInt m, UInt n = 0){
padding_m = m;
padding_n = n;
}
virtual UInt getPaddedDim(UInt nb_data) {
return nb_data;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
/// padding informations
UInt padding_n, padding_m;
};
/* -------------------------------------------------------------------------- */
template<class input_type, class output_type>
class PadderGeneric :
public ComputeFunctor<input_type, output_type > , public PadderInterface {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PadderGeneric() : PadderInterface(){}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline output_type pad(const input_type & in,__attribute__((unused)) UInt nb_data) {
return in; // trick due to the fact that IOHelper padds the vectors (avoid a copy of data)
}
};
/* -------------------------------------------------------------------------- */
template<class T>
class PadderGeneric<Vector<T>, Matrix<T> > :
public ComputeFunctor<Vector<T>, Matrix<T> > , public PadderInterface {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
inline Matrix<T> pad(const Vector<T> & _in,
UInt nrows, UInt ncols,
UInt nb_data) {
Matrix<T> in(_in.storage(), nrows, ncols);
if(padding_m <= nrows && padding_n*nb_data <= ncols)
return in;
else {
Matrix<T> ret(padding_m, padding_n * nb_data);
UInt nb_cols_per_data = in.cols() / nb_data;
for (UInt d = 0; d < nb_data; ++d)
for (UInt i = 0; i < in.rows(); ++i)
for (UInt j = 0; j < nb_cols_per_data; ++j)
ret(i, j + d * padding_n) = in(i, j + d * nb_cols_per_data);
return ret;
}
}
};
/* -------------------------------------------------------------------------- */
__END_AKANTU__
__END_AKANTU_DUMPER__
#endif /* __AKANTU_DUMPER_PADDING_HELPER_HH__ */
diff --git a/src/io/dumper/dumper_paraview.cc b/src/io/dumper/dumper_paraview.cc
index d41e9469b..5801c0e84 100644
--- a/src/io/dumper/dumper_paraview.cc
+++ b/src/io/dumper/dumper_paraview.cc
@@ -1,66 +1,67 @@
/**
* @file dumper_paraview.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Oct 26 2012
- * @date last modification: Tue Oct 29 2013
+ * @date creation: Sun Sep 26 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief implementations of DumperParaview
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <io_helper.hh>
#include "dumper_paraview.hh"
#include "static_communicator.hh"
#include <fstream>
__BEGIN_AKANTU__
DumperParaview::DumperParaview(const std::string & filename,
const std::string & directory,
bool parallel) : DumperIOHelper() {
iohelper::DumperParaview * dumper_para = new iohelper::DumperParaview();
dumper = dumper_para;
setBaseName(filename);
this->setParallelContext(parallel);
dumper_para->setMode(iohelper::BASE64);
dumper_para->setPrefix(directory);
dumper_para->init();
}
/* -------------------------------------------------------------------------- */
DumperParaview::~DumperParaview() {
}
/* -------------------------------------------------------------------------- */
void DumperParaview::setBaseName(const std::string & basename) {
DumperIOHelper::setBaseName(basename);
static_cast<iohelper::DumperParaview*>(dumper)->setVTUSubDirectory(filename + "-VTU");
}
__END_AKANTU__
diff --git a/src/io/dumper/dumper_paraview.hh b/src/io/dumper/dumper_paraview.hh
index 5bd22735e..81812ea5f 100644
--- a/src/io/dumper/dumper_paraview.hh
+++ b/src/io/dumper/dumper_paraview.hh
@@ -1,73 +1,74 @@
/**
* @file dumper_paraview.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Oct 26 2012
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Dumper Paraview using IOHelper
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPER_PARAVIEW_HH__
#define __AKANTU_DUMPER_PARAVIEW_HH__
#include "dumper_iohelper.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class DumperParaview : public DumperIOHelper {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DumperParaview(const std::string & filename,
const std::string & directory = "./paraview",
bool parallel = true);
virtual ~DumperParaview();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
// void dump();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
void setBaseName(const std::string & basename);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
__END_AKANTU__
#endif /* __AKANTU_DUMPER_PARAVIEW_HH__ */
diff --git a/src/io/dumper/dumper_quadrature_point_iterator.hh b/src/io/dumper/dumper_quadrature_point_iterator.hh
index abf4437b9..7c740aa4e 100644
--- a/src/io/dumper/dumper_quadrature_point_iterator.hh
+++ b/src/io/dumper/dumper_quadrature_point_iterator.hh
@@ -1,77 +1,77 @@
/**
* @file dumper_quadrature_point_iterator.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Thu Sep 17 2015
*
* @brief Description of quadrature point iterator
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_QUADRATURE_POINT_ITERATOR_HH__
#define __AKANTU_DUMPER_QUADRATURE_POINT_ITERATOR_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_elemental_field.hh"
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template<typename types>
class quadrature_point_iterator
: public element_iterator<types, quadrature_point_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef element_iterator<types, dumper::quadrature_point_iterator> parent;
typedef typename types::data_type data_type;
typedef typename types::return_type return_type;
typedef typename types::field_type field_type;
typedef typename types::array_iterator array_iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
quadrature_point_iterator(const field_type & field,
const typename field_type::type_iterator & t_it,
const typename field_type::type_iterator & t_it_end,
const array_iterator & array_it,
const array_iterator & array_it_end,
const GhostType ghost_type = _not_ghost) :
parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) { }
return_type operator*() {
return *this->array_it;
}
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_QUADRATURE_POINT_ITERATOR_HH__ */
diff --git a/src/io/dumper/dumper_text.cc b/src/io/dumper/dumper_text.cc
index 9007611ee..3374abe4e 100644
--- a/src/io/dumper/dumper_text.cc
+++ b/src/io/dumper/dumper_text.cc
@@ -1,118 +1,119 @@
/**
* @file dumper_text.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Fri May 17 2013
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief implementation of text dumper
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <io_helper.hh>
#include "dumper_text.hh"
#include "dumper_nodal_field.hh"
#include "mesh.hh"
#include "static_communicator.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
DumperText::DumperText(const std::string & basename,
iohelper::TextDumpMode mode,
bool parallel) : DumperIOHelper() {
AKANTU_DEBUG_IN();
iohelper::DumperText * dumper_text = new iohelper::DumperText(mode);
this->dumper = dumper_text;
this->setBaseName(basename);
this->setParallelContext(parallel);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DumperText::registerMesh(const Mesh & mesh,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
registerField("position",
new dumper::NodalField<Real>(mesh.getNodes()));
// in parallel we need node type
UInt nb_proc = StaticCommunicator::getStaticCommunicator().getNbProc();
if (nb_proc > 1) {
registerField("nodes_type",
new dumper::NodalField<Int>(mesh.getNodesType()));
}
}
/* -------------------------------------------------------------------------- */
void DumperText::registerFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
registerField("position",
new dumper::NodalField<Real,
true>(mesh.getNodes(),
0,
0,
&nodes_filter));
// in parallel we need node type
UInt nb_proc = StaticCommunicator::getStaticCommunicator().getNbProc();
if (nb_proc > 1) {
registerField("nodes_type",
new dumper::NodalField<Int,
true>(mesh.getNodesType(),
0,
0,
&nodes_filter));
}
}
/* -------------------------------------------------------------------------- */
void DumperText::setBaseName(const std::string & basename) {
AKANTU_DEBUG_IN();
DumperIOHelper::setBaseName(basename);
static_cast<iohelper::DumperText*>(this->dumper)->setDataSubDirectory(this->filename
+ "-DataFiles");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DumperText::setPrecision(UInt prec) {
AKANTU_DEBUG_IN();
static_cast<iohelper::DumperText*>(this->dumper)->setPrecision(prec);
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/io/dumper/dumper_text.hh b/src/io/dumper/dumper_text.hh
index 142fbb9ea..cd698f947 100644
--- a/src/io/dumper/dumper_text.hh
+++ b/src/io/dumper/dumper_text.hh
@@ -1,87 +1,88 @@
/**
* @file dumper_text.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Fri May 17 2013
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief to dump into a text file
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "dumper_iohelper.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPER_TEXT_HH__
#define __AKANTU_DUMPER_TEXT_HH__
/* -------------------------------------------------------------------------- */
#include <io_helper.hh>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class DumperText : public DumperIOHelper {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DumperText(const std::string & basename = "dumper_text",
iohelper::TextDumpMode mode = iohelper::_tdm_space,
bool parallel = true);
virtual ~DumperText() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void registerMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
virtual void registerFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
virtual void setBaseName(const std::string & basename);
private:
void registerNodeTypeField();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
void setPrecision(UInt prec);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
__END_AKANTU__
#endif /* __AKANTU_DUMPER_TEXT_HH__ */
diff --git a/src/io/dumper/dumper_type_traits.hh b/src/io/dumper/dumper_type_traits.hh
index b1c6566f0..be7ce42ce 100644
--- a/src/io/dumper/dumper_type_traits.hh
+++ b/src/io/dumper/dumper_type_traits.hh
@@ -1,99 +1,99 @@
/**
* @file dumper_type_traits.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Mon Sep 21 2015
*
* @brief Type traits for field properties
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_TYPE_TRAITS_HH__
#define __AKANTU_DUMPER_TYPE_TRAITS_HH__
/* -------------------------------------------------------------------------- */
#include "element_type_map.hh"
#include "element_type_map_filter.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <class data, class ret, class field>
struct TypeTraits {
//! the stored data (real, int, uint, ...)
typedef data data_type;
//! the type returned by the operator *
typedef ret return_type;
//! the field type (ElementTypeMap or ElementTypeMapFilter)
typedef field field_type;
//! the type over which we iterate
typedef typename field_type::type it_type;
//! the type of array (Array<T> or ArrayFilter<T>)
typedef typename field_type::array_type array_type;
//! the iterator over the array
typedef typename array_type::const_vector_iterator array_iterator;
};
/* -------------------------------------------------------------------------- */
// specialization for the case in which input and output types are the same
template <class T, template <class> class ret, bool filtered>
struct SingleType
: public TypeTraits<T,ret<T>,ElementTypeMapArray<T> >{
};
/* -------------------------------------------------------------------------- */
// same as before but for filtered data
template <class T, template <class> class ret>
struct SingleType<T,ret,true> :
public TypeTraits<T,ret<T>, ElementTypeMapArrayFilter<T> >{
};
/* -------------------------------------------------------------------------- */
// specialization for the case in which input and output types are different
template <class it_type, class data_type, template <class> class ret,
bool filtered>
struct DualType
: public TypeTraits<data_type,ret<data_type>, ElementTypeMapArray<it_type> >{
};
/* -------------------------------------------------------------------------- */
// same as before but for filtered data
template <class it_type, class data_type,template <class> class ret>
struct DualType<it_type,data_type,ret,true> :
public TypeTraits<data_type,ret<data_type>, ElementTypeMapArrayFilter<it_type> >{
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
/* -------------------------------------------------------------------------- */
#endif /* __AKANTU_DUMPER_TYPE_TRAITS_HH__ */
diff --git a/src/io/dumper/dumper_variable.hh b/src/io/dumper/dumper_variable.hh
index ac75e3402..0bdda9da1 100644
--- a/src/io/dumper/dumper_variable.hh
+++ b/src/io/dumper/dumper_variable.hh
@@ -1,118 +1,118 @@
/**
* @file dumper_variable.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Tue Jun 04 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief template of variable
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPER_IOHELPER_TMPL_VARIABLE_HH__
#define __AKANTU_DUMPER_IOHELPER_TMPL_VARIABLE_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
/// Variable interface
class VariableBase {
public:
VariableBase() {};
virtual ~VariableBase() {};
virtual void registerToDumper(const std::string & id, iohelper::Dumper & dumper) = 0;
};
/* -------------------------------------------------------------------------- */
template<typename T, bool is_scal = is_scalar<T>::value >
class Variable : public VariableBase {
public:
Variable(const T & t) : vari(t) {}
virtual void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) {
dumper.addVariable(id, *this);
}
const T & operator[](UInt i) const {
return vari[i];
}
UInt getDim() { return vari.size(); }
iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
protected:
const T & vari;
};
/* -------------------------------------------------------------------------- */
template<typename T>
class Variable<Vector<T>, false> : public VariableBase {
public:
Variable(const Vector<T> & t) : vari(t) {}
virtual void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) {
dumper.addVariable(id, *this);
}
const T & operator[](UInt i) const {
return vari[i];
}
UInt getDim() { return vari.size(); }
iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
protected:
const Vector<T> & vari;
};
/* -------------------------------------------------------------------------- */
template<typename T>
class Variable<T, true> : public VariableBase {
public:
Variable(const T & t) : vari(t) {}
virtual void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) {
dumper.addVariable(id, *this);
}
const T & operator[](__attribute__((unused)) UInt i) const {
return vari;
}
UInt getDim() { return 1; }
iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
protected:
const T & vari;
};
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_IOHELPER_TMPL_VARIABLE_HH__ */
diff --git a/src/io/mesh_io.cc b/src/io/mesh_io.cc
index 913385b26..97694ab27 100644
--- a/src/io/mesh_io.cc
+++ b/src/io/mesh_io.cc
@@ -1,152 +1,154 @@
/**
* @file mesh_io.cc
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Jul 15 2010
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Mon Jun 01 2015
*
* @brief common part for all mesh io classes
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "mesh_io.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
MeshIO::MeshIO() {
canReadSurface = false;
canReadExtendedData = false;
}
/* -------------------------------------------------------------------------- */
MeshIO::~MeshIO() {
}
/* -------------------------------------------------------------------------- */
MeshIO * MeshIO::getMeshIO(const std::string & filename, const MeshIOType & type) {
MeshIOType t = type;
if(type == _miot_auto) {
std::string::size_type idx = filename.rfind('.');
std::string ext;
if(idx != std::string::npos) {
ext = filename.substr(idx+1);
}
if(ext == "msh") { t = _miot_gmsh;
} else if(ext == "diana") { t = _miot_diana;
} else if(ext == "inp") { t = _miot_abaqus;
} else AKANTU_EXCEPTION("Cannot guess the type of file of "
<< filename << " (ext "<< ext <<"). "
<< "Please provide the MeshIOType to the read function");
}
switch(t) {
case _miot_gmsh : return new MeshIOMSH();
#if defined(AKANTU_STRUCTURAL_MECHANICS)
case _miot_gmsh_struct : return new MeshIOMSHStruct();
#endif
case _miot_diana : return new MeshIODiana();
case _miot_abaqus : return new MeshIOAbaqus();
default:
return NULL;
}
}
/* -------------------------------------------------------------------------- */
void MeshIO::read(const std::string & filename, Mesh & mesh, const MeshIOType & type) {
MeshIO * mesh_io = getMeshIO(filename, type);
mesh_io->read(filename, mesh);
delete mesh_io;
}
/* -------------------------------------------------------------------------- */
void MeshIO::write(const std::string & filename, Mesh & mesh, const MeshIOType & type) {
MeshIO * mesh_io = getMeshIO(filename, type);
mesh_io->write(filename, mesh);
delete mesh_io;
}
/* -------------------------------------------------------------------------- */
void MeshIO::constructPhysicalNames(const std::string & tag_name,
Mesh & mesh) {
if(!phys_name_map.empty()) {
for(Mesh::type_iterator type_it = mesh.firstType();
type_it != mesh.lastType();
++type_it) {
Array<std::string> * name_vec =
mesh.getDataPointer<std::string>("physical_names", *type_it);
const Array<UInt> & tags_vec =
mesh.getData<UInt>(tag_name, *type_it);
for(UInt i(0); i < tags_vec.getSize(); i++) {
std::map<UInt, std::string>::const_iterator map_it
= phys_name_map.find(tags_vec(i));
if(map_it == phys_name_map.end()) {
std::stringstream sstm;
sstm << tags_vec(i);
name_vec->operator()(i) = sstm.str();
} else {
name_vec->operator()(i) = map_it->second;
}
}
}
}
}
/* -------------------------------------------------------------------------- */
void MeshIO::printself(std::ostream & stream, int indent) const{
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
if (phys_name_map.size()){
stream << space << "Physical map:" << std::endl;
std::map<UInt, std::string>::const_iterator it = phys_name_map.begin();
std::map<UInt, std::string>::const_iterator end = phys_name_map.end();
for (; it!=end; ++it) {
stream << space << it->first << ": " << it->second << std::endl;
}
}
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/io/mesh_io.hh b/src/io/mesh_io.hh
index d7916f62d..6420037c3 100644
--- a/src/io/mesh_io.hh
+++ b/src/io/mesh_io.hh
@@ -1,125 +1,127 @@
/**
* @file mesh_io.hh
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Mon Jun 01 2015
*
* @brief interface of a mesh io class, reader and writer
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_IO_HH__
#define __AKANTU_MESH_IO_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class MeshIO {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshIO();
virtual ~MeshIO();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void read(const std::string & filename, Mesh & mesh, const MeshIOType & type);
void write(const std::string & filename, Mesh & mesh, const MeshIOType & type);
/// read a mesh from the file
virtual void read(__attribute__((unused)) const std::string & filename,
__attribute__((unused)) Mesh & mesh) {
}
/// write a mesh to a file
virtual void write(__attribute__((unused)) const std::string & filename,
__attribute__((unused)) const Mesh & mesh) {}
/// function to request the manual construction of the physical names maps
virtual void constructPhysicalNames(const std::string & tag_name,
Mesh & mesh);
/// method to permit to be printed to a generic stream
virtual void printself(std::ostream & stream, int indent = 0) const;
/// static contruction of a meshio object
static MeshIO * getMeshIO(const std::string & filename, const MeshIOType & type);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
std::map<UInt, std::string> & getPhysicalNameMap(){
return phys_name_map;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
bool canReadSurface;
bool canReadExtendedData;
/// correspondance between a tag and physical names (if applicable)
std::map<UInt, std::string> phys_name_map;
};
/* -------------------------------------------------------------------------- */
inline std::ostream & operator <<(std::ostream & stream, const MeshIO &_this) {
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include "mesh_io_msh.hh"
#include "mesh_io_diana.hh"
#include "mesh_io_abaqus.hh"
#if defined(AKANTU_STRUCTURAL_MECHANICS)
# include "mesh_io_msh_struct.hh"
#endif
#endif /* __AKANTU_MESH_IO_HH__ */
diff --git a/src/io/mesh_io/mesh_io_abaqus.cc b/src/io/mesh_io/mesh_io_abaqus.cc
index babc11e22..75092a544 100644
--- a/src/io/mesh_io/mesh_io_abaqus.cc
+++ b/src/io/mesh_io/mesh_io_abaqus.cc
@@ -1,548 +1,549 @@
/**
* @file mesh_io_abaqus.cc
*
+ * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Fri Sep 19 2014
+ * @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 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
// std library header files
#include <fstream>
// 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
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
// #include <boost/spirit/include/phoenix_core.hpp>
// #include <boost/spirit/include/phoenix_fusion.hpp>
// #include <boost/spirit/include/phoenix_object.hpp>
// #include <boost/spirit/include/phoenix_container.hpp>
// #include <boost/spirit/include/phoenix_operator.hpp>
// #include <boost/spirit/include/phoenix_bind.hpp>
// #include <boost/spirit/include/phoenix_stl.hpp>
/* -------------------------------------------------------------------------- */
__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 <typename, typename, typename>
struct result { typedef void type; };
template <typename Iterator>
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<class Mesh, class ET, class ID, class V, class NodeMap, class ElemMap>
struct result { typedef void type; };
template<class Mesh, class ET, class ID, class V, class NodeMap, class ElemMap>
void operator()(Mesh & mesh,
const ET & type,
const ID & id,
const V & conn,
const NodeMap & nodes_mapping,
ElemMap & elements_mapping) const {
Vector<UInt> 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<UInt> & 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);
}
};
struct lazy_node_read_ {
template<class Mesh, class ID, class V, class Map>
struct result { typedef void type; };
template<class Mesh, class ID, class V, class Map>
void operator()(Mesh & mesh,
const ID & id,
const V & pos,
Map & nodes_mapping) const {
Vector<Real> 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);
}
};
/* ------------------------------------------------------------------------ */
struct lazy_element_group_create_ {
template<class Mesh, class S> struct result { typedef ElementGroup & type; };
template<class Mesh, class S>
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);
}
}
};
struct lazy_add_element_to_group_ {
template<class EG, class ID, class Map>
struct result { typedef void type; };
template<class EG, class ID, class Map>
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() << ".");
el_grp->add(eit->second, true, false);
}
};
/* ------------------------------------------------------------------------ */
struct lazy_node_group_create_ {
template<class Mesh, class S> struct result { typedef NodeGroup & type; };
template<class Mesh, class S>
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());
}
}
};
struct lazy_add_node_to_group_ {
template<class NG, class ID, class Map>
struct result { typedef void type; };
template<class NG, class ID, class Map>
void operator()(NG * node_grp,
const ID & node,
const Map & nodes_mapping) const {
typename 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);
}
};
struct lazy_optimize_group_ {
template<class G> struct result { typedef void type; };
template<class G> void operator()(G * grp) const {
grp->optimize();
}
};
}
/* -------------------------------------------------------------------------- */
template<class Iterator>
struct AbaqusSkipper : qi::grammar<Iterator> {
AbaqusSkipper() : AbaqusSkipper::base_type(skip,
"abaqus_skipper") {
skip
= (ascii::space - spirit::eol)
| "**" >> *(qi::char_ - spirit::eol) >> spirit::eol
;
}
qi::rule<Iterator> skip;
};
/* -------------------------------------------------------------------------- */
template<class Iterator, typename Skipper = AbaqusSkipper<Iterator> >
struct AbaqusMeshGrammar : qi::grammar<Iterator, void(),
Skipper> {
public:
AbaqusMeshGrammar(Mesh & mesh) : AbaqusMeshGrammar::base_type(start,
"abaqus_mesh_reader"),
mesh(mesh) {
phx::function<mesh_io_abaqus_lazy_eval::mesh_abaqus_error_handler_> const error_handler
= mesh_io_abaqus_lazy_eval::mesh_abaqus_error_handler_();
phx::function<mesh_io_abaqus_lazy_eval::lazy_element_read_> lazy_element_read;
phx::function<mesh_io_abaqus_lazy_eval::lazy_node_read_> lazy_node_read;
phx::function<mesh_io_abaqus_lazy_eval::lazy_element_group_create_> lazy_element_group_create;
phx::function<mesh_io_abaqus_lazy_eval::lazy_add_element_to_group_> lazy_add_element_to_group;
phx::function<mesh_io_abaqus_lazy_eval::lazy_node_group_create_> lazy_node_group_create;
phx::function<mesh_io_abaqus_lazy_eval::lazy_add_node_to_group_> lazy_add_node_to_group;
phx::function<mesh_io_abaqus_lazy_eval::lazy_optimize_group_> lazy_optimize_group;
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)) ]
>> 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)) ]
>> spirit::eol
)
;
elements_set
= (
(
( qi::char_(',') >> qi::no_case[ qi::lit("elset") ] >> '='
>> value [ lbs::_a = &lazy_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)
)
]
)
]
) [ lazy_optimize_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) ]
)
^ *(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)
)
]
)
]
) [ lazy_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);
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
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");
}
public:
AKANTU_GET_MACRO(MaterialNames, material_names, const std::vector<std::string> &);
/* ------------------------------------------------------------------------ */
/* Rules */
/* ------------------------------------------------------------------------ */
private:
qi::rule<Iterator, void(), Skipper> start;
qi::rule<Iterator, std::vector<int>(), Skipper> connectivity;
qi::rule<Iterator, std::vector<Real>(), Skipper> node_position;
qi::rule<Iterator, void(), Skipper> nodes, any_section, header, material;
qi::rule<Iterator, void(), qi::locals<ElementType>, Skipper> elements;
qi::rule<Iterator, void(), qi::locals<ElementGroup *>, Skipper> elements_set;
qi::rule<Iterator, void(), qi::locals<NodeGroup *>, Skipper> nodes_set;
qi::rule<Iterator, std::string(), Skipper> key, value, option, keyword, any_line;
qi::real_parser< Real, qi::real_policies<Real> > real;
qi::symbols<char, ElementType> 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<UInt, UInt> abaqus_nodes_to_akantu;
/// correspondance between the element number in the abaqus file and the
/// Element in the akantu mesh
std::map<UInt, Element> abaqus_elements_to_akantu;
/// list of the material names
std::vector<std::string> 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<char>(infile),
std::istream_iterator<char>(),
std::back_inserter(storage));
typedef std::string::const_iterator iterator_t;
typedef AbaqusSkipper <iterator_t> skipper;
typedef AbaqusMeshGrammar<iterator_t, skipper> 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<std::string>::const_iterator mnit = g.getMaterialNames().begin();
std::vector<std::string>::const_iterator mnend = g.getMaterialNames().end();
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<std::string> & abaqus_material
= this->getData<std::string>(mesh, "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;
}
}
}
}
this->setNbGlobalNodes(mesh, mesh.getNodes().getSize());
MeshUtils::fillElementToSubElementsData(mesh);
}
__END_AKANTU__
diff --git a/src/io/mesh_io/mesh_io_abaqus.hh b/src/io/mesh_io/mesh_io_abaqus.hh
index 4ed265243..3cd861fec 100644
--- a/src/io/mesh_io/mesh_io_abaqus.hh
+++ b/src/io/mesh_io/mesh_io_abaqus.hh
@@ -1,59 +1,60 @@
/**
* @file mesh_io_abaqus.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Sun Sep 26 2010
+ * @date last modification: Tue Jun 30 2015
*
* @brief read a mesh from an abaqus input file
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "mesh_io.hh"
#include "mesh_accessor.hh"
#ifndef __AKANTU_MESH_IO_ABAQUS_HH__
#define __AKANTU_MESH_IO_ABAQUS_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class MeshIOAbaqus : public MeshIO, private MeshAccessor {
public:
MeshIOAbaqus();
virtual ~MeshIOAbaqus();
/// read a mesh from the file
virtual void read(const std::string & filename, Mesh & mesh);
/// write a mesh to a file
// virtual void write(const std::string & filename, const Mesh & mesh);
private:
/// correspondence between msh element types and akantu element types
std::map<std::string, ElementType> _abaqus_to_akantu_element_types;
};
__END_AKANTU__
#endif /* __AKANTU_MESH_IO_ABAQUS_HH__ */
diff --git a/src/io/mesh_io/mesh_io_diana.cc b/src/io/mesh_io/mesh_io_diana.cc
index 33c9452fa..287e7a577 100644
--- a/src/io/mesh_io/mesh_io_diana.cc
+++ b/src/io/mesh_io/mesh_io_diana.cc
@@ -1,580 +1,582 @@
/**
* @file mesh_io_diana.cc
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
- * @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
*
* @date creation: Sat Mar 26 2011
- * @date last modification: Thu Mar 27 2014
+ * @date last modification: Thu Nov 19 2015
*
* @brief handles diana meshes
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "mesh_io_diana.hh"
#include "mesh_utils.hh"
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
#include <string.h>
/* -------------------------------------------------------------------------- */
#include <stdio.h>
__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<std::string, ElementType>::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<UInt>::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<Real> & nodes = const_cast<Array<Real> &>(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<UInt> & 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<UInt> * list_ids = new Array<UInt>(0, 1, name);
UInt s = 1;
bool end = false;
while (!end) {
while (!str->eof() && s != 0) {
std::set<UInt> interval;
s = readInterval(*str, interval);
std::set<UInt>::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<UInt> * 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[node_per_element];
// used if element is written on two lines
UInt j_last;
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;
}
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<UInt>("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<UInt> 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<UInt> & data =
*(mesh.getDataPointer<UInt>("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<std::string, Real> 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<std::string, std::string>::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/mesh_io/mesh_io_diana.hh b/src/io/mesh_io/mesh_io_diana.hh
index ff5f24ddf..737c4de68 100644
--- a/src/io/mesh_io/mesh_io_diana.hh
+++ b/src/io/mesh_io/mesh_io_diana.hh
@@ -1,105 +1,107 @@
/**
* @file mesh_io_diana.hh
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
- * @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
*
- * @date creation: Sat Mar 26 2011
- * @date last modification: Mon Aug 19 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Nov 19 2015
*
* @brief diana mesh reader description
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_IO_DIANA_HH__
#define __AKANTU_MESH_IO_DIANA_HH__
/* -------------------------------------------------------------------------- */
#include "mesh_io.hh"
/* -------------------------------------------------------------------------- */
#include <vector>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class MeshIODiana : public MeshIO {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshIODiana();
virtual ~MeshIODiana();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// read a mesh from the file
virtual void read(const std::string & filename, Mesh & mesh);
/// write a mesh to a file
virtual void write(const std::string & filename, const Mesh & mesh);
private:
std::string readCoordinates(std::ifstream & infile, Mesh & mesh,
UInt & first_node_number);
std::string readElements(std::ifstream & infile, Mesh & mesh,
UInt first_node_number);
std::string readGroups(std::ifstream & infile, Mesh & mesh, UInt first_node_number);
std::string readConnectivity(std::ifstream & infile, Mesh & mesh,
UInt first_node_number);
std::string readMaterialElement(std::ifstream & infile, Mesh & mesh);
std::string readMaterial(std::ifstream & infile,
const std::string & filename);
UInt readInterval(std::stringstream & line, std::set<UInt> & interval);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
std::map<std::string, ElementType> _diana_to_akantu_element_types;
std::map<std::string, std::string> _diana_to_akantu_mat_prop;
/// order in witch element as to be read, akantu_node_order = _read_order[diana_node_order]
std::map<ElementType, UInt *> _read_order;
std::map<UInt, Element> diana_element_number_to_elements;
std::map<Element, UInt> akantu_number_to_diana_number;
};
__END_AKANTU__
#endif /* __AKANTU_MESH_IO_DIANA_HH__ */
diff --git a/src/io/mesh_io/mesh_io_msh.cc b/src/io/mesh_io/mesh_io_msh.cc
index 8d5712792..44fad08c2 100644
--- a/src/io/mesh_io/mesh_io_msh.cc
+++ b/src/io/mesh_io/mesh_io_msh.cc
@@ -1,969 +1,973 @@
/**
* @file mesh_io_msh.cc
*
+ * @author Dana Christen <dana.christen@gmail.com>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Fri Jul 04 2014
+ * @date last modification: Mon Dec 07 2015
*
* @brief Read/Write for MSH files generated by gmsh
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -----------------------------------------------------------------------------
Version (Legacy) 1.0
$NOD
number-of-nodes
node-number x-coord y-coord z-coord
...
$ENDNOD
$ELM
number-of-elements
elm-number elm-type reg-phys reg-elem number-of-nodes node-number-list
...
$ENDELM
-----------------------------------------------------------------------------
Version 2.1
$MeshFormat
version-number file-type data-size
$EndMeshFormat
$Nodes
number-of-nodes
node-number x-coord y-coord z-coord
...
$EndNodes
$Elements
number-of-elements
elm-number elm-type number-of-tags < tag > ... node-number-list
...
$EndElements
$PhysicalNames
number-of-names
physical-dimension physical-number "physical-name"
...
$EndPhysicalNames
$NodeData
number-of-string-tags
< "string-tag" >
...
number-of-real-tags
< real-tag >
...
number-of-integer-tags
< integer-tag >
...
node-number value ...
...
$EndNodeData
$ElementData
number-of-string-tags
< "string-tag" >
...
number-of-real-tags
< real-tag >
...
number-of-integer-tags
< integer-tag >
...
elm-number value ...
...
$EndElementData
$ElementNodeData
number-of-string-tags
< "string-tag" >
...
number-of-real-tags
< real-tag >
...
number-of-integer-tags
< integer-tag >
...
elm-number number-of-nodes-per-element value ...
...
$ElementEndNodeData
-----------------------------------------------------------------------------
elem-type
1: 2-node line.
2: 3-node triangle.
3: 4-node quadrangle.
4: 4-node tetrahedron.
5: 8-node hexahedron.
6: 6-node prism.
7: 5-node pyramid.
8: 3-node second order line
9: 6-node second order triangle
10: 9-node second order quadrangle
11: 10-node second order tetrahedron
12: 27-node second order hexahedron
13: 18-node second order prism
14: 14-node second order pyramid
15: 1-node point.
16: 8-node second order quadrangle
17: 20-node second order hexahedron
18: 15-node second order prism
19: 13-node second order pyramid
20: 9-node third order incomplete triangle
21: 10-node third order triangle
22: 12-node fourth order incomplete triangle
23: 15-node fourth order triangle
24: 15-node fifth order incomplete triangle
25: 21-node fifth order complete triangle
26: 4-node third order edge
27: 5-node fourth order edge
28: 6-node fifth order edge
29: 20-node third order tetrahedron
30: 35-node fourth order tetrahedron
31: 56-node fifth order tetrahedron
-------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "mesh_io.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// The boost spirit is a work on the way it does not compile so I kept the
// current code. The current code does not handle files generated on Windows
// <CRLF>
// #include <boost/config/warning_disable.hpp>
// #include <boost/spirit/include/qi.hpp>
// #include <boost/spirit/include/phoenix_core.hpp>
// #include <boost/spirit/include/phoenix_fusion.hpp>
// #include <boost/spirit/include/phoenix_object.hpp>
// #include <boost/spirit/include/phoenix_container.hpp>
// #include <boost/spirit/include/phoenix_operator.hpp>
// #include <boost/spirit/include/phoenix_bind.hpp>
// #include <boost/spirit/include/phoenix_stl.hpp>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Methods Implentations */
/* -------------------------------------------------------------------------- */
MeshIOMSH::MeshIOMSH() {
canReadSurface = true;
canReadExtendedData = true;
_msh_nodes_per_elem[_msh_not_defined] = 0;
_msh_nodes_per_elem[_msh_segment_2] = 2;
_msh_nodes_per_elem[_msh_triangle_3] = 3;
_msh_nodes_per_elem[_msh_quadrangle_4] = 4;
_msh_nodes_per_elem[_msh_tetrahedron_4] = 4;
_msh_nodes_per_elem[_msh_hexahedron_8] = 8;
_msh_nodes_per_elem[_msh_prism_1] = 6;
_msh_nodes_per_elem[_msh_pyramid_1] = 1;
_msh_nodes_per_elem[_msh_segment_3] = 3;
_msh_nodes_per_elem[_msh_triangle_6] = 6;
_msh_nodes_per_elem[_msh_quadrangle_9] = 9;
_msh_nodes_per_elem[_msh_tetrahedron_10] = 10;
_msh_nodes_per_elem[_msh_hexahedron_27] = 27;
_msh_nodes_per_elem[_msh_hexahedron_20] = 20;
_msh_nodes_per_elem[_msh_prism_18] = 18;
_msh_nodes_per_elem[_msh_prism_15] = 15;
_msh_nodes_per_elem[_msh_pyramid_14] = 14;
_msh_nodes_per_elem[_msh_point] = 1;
_msh_nodes_per_elem[_msh_quadrangle_8] = 8;
_msh_to_akantu_element_types[_msh_not_defined] = _not_defined;
_msh_to_akantu_element_types[_msh_segment_2] = _segment_2;
_msh_to_akantu_element_types[_msh_triangle_3] = _triangle_3;
_msh_to_akantu_element_types[_msh_quadrangle_4] = _quadrangle_4;
_msh_to_akantu_element_types[_msh_tetrahedron_4] = _tetrahedron_4;
_msh_to_akantu_element_types[_msh_hexahedron_8] = _hexahedron_8;
_msh_to_akantu_element_types[_msh_prism_1] = _pentahedron_6;
_msh_to_akantu_element_types[_msh_pyramid_1] = _not_defined;
_msh_to_akantu_element_types[_msh_segment_3] = _segment_3;
_msh_to_akantu_element_types[_msh_triangle_6] = _triangle_6;
_msh_to_akantu_element_types[_msh_quadrangle_9] = _not_defined;
_msh_to_akantu_element_types[_msh_tetrahedron_10] = _tetrahedron_10;
_msh_to_akantu_element_types[_msh_hexahedron_27] = _not_defined;
_msh_to_akantu_element_types[_msh_hexahedron_20] = _hexahedron_20;
_msh_to_akantu_element_types[_msh_prism_18] = _not_defined;
_msh_to_akantu_element_types[_msh_prism_15] = _pentahedron_15;
_msh_to_akantu_element_types[_msh_pyramid_14] = _not_defined;
_msh_to_akantu_element_types[_msh_point] = _point_1;
_msh_to_akantu_element_types[_msh_quadrangle_8] = _quadrangle_8;
_akantu_to_msh_element_types[_not_defined] = _msh_not_defined;
_akantu_to_msh_element_types[_segment_2] = _msh_segment_2;
_akantu_to_msh_element_types[_segment_3] = _msh_segment_3;
_akantu_to_msh_element_types[_triangle_3] = _msh_triangle_3;
_akantu_to_msh_element_types[_triangle_6] = _msh_triangle_6;
_akantu_to_msh_element_types[_tetrahedron_4] = _msh_tetrahedron_4;
_akantu_to_msh_element_types[_tetrahedron_10] = _msh_tetrahedron_10;
_akantu_to_msh_element_types[_quadrangle_4] = _msh_quadrangle_4;
_akantu_to_msh_element_types[_quadrangle_8] = _msh_quadrangle_8;
_akantu_to_msh_element_types[_hexahedron_8] = _msh_hexahedron_8;
_akantu_to_msh_element_types[_hexahedron_20] = _msh_hexahedron_20;
_akantu_to_msh_element_types[_pentahedron_6] = _msh_prism_1;
_akantu_to_msh_element_types[_pentahedron_15] = _msh_prism_15;
_akantu_to_msh_element_types[_point_1] = _msh_point;
#if defined(AKANTU_STRUCTURAL_MECHANICS)
_akantu_to_msh_element_types[_bernoulli_beam_2] = _msh_segment_2;
_akantu_to_msh_element_types[_bernoulli_beam_3] = _msh_segment_2;
_akantu_to_msh_element_types[_kirchhoff_shell] = _msh_triangle_3;
#endif
std::map<ElementType, MSHElementType>::iterator it;
for (it = _akantu_to_msh_element_types.begin();
it != _akantu_to_msh_element_types.end(); ++it) {
UInt nb_nodes = _msh_nodes_per_elem[it->second];
std::vector<UInt> tmp(nb_nodes);
for (UInt i = 0; i < nb_nodes; ++i) {
tmp[i] = i;
}
switch (it->first) {
case _tetrahedron_10:
tmp[8] = 9;
tmp[9] = 8;
break;
case _pentahedron_6:
tmp[0] = 2;
tmp[1] = 0;
tmp[2] = 1;
tmp[3] = 5;
tmp[4] = 3;
tmp[5] = 4;
break;
case _pentahedron_15:
tmp[0] = 2;
tmp[1] = 0;
tmp[2] = 1;
tmp[3] = 5;
tmp[4] = 3;
tmp[5] = 4;
tmp[6] = 8;
tmp[8] = 11;
tmp[9] = 6;
tmp[10] = 9;
tmp[11] = 10;
tmp[12] = 14;
tmp[14] = 12;
break;
case _hexahedron_20:
tmp[9] = 11;
tmp[10] = 12;
tmp[11] = 9;
tmp[12] = 13;
tmp[13] = 10;
tmp[17] = 19;
tmp[18] = 17;
tmp[19] = 18;
break;
default:
// nothing to change
break;
}
_read_order[it->first] = tmp;
}
}
/* -------------------------------------------------------------------------- */
MeshIOMSH::~MeshIOMSH() {}
/* -------------------------------------------------------------------------- */
/* Spirit stuff */
/* -------------------------------------------------------------------------- */
// namespace _parser {
// namespace spirit = ::boost::spirit;
// namespace qi = ::boost::spirit::qi;
// namespace ascii = ::boost::spirit::ascii;
// namespace lbs = ::boost::spirit::qi::labels;
// namespace phx = ::boost::phoenix;
// /* ------------------------------------------------------------------------
// */
// /* Lazy functors */
// /* ------------------------------------------------------------------------
// */
// struct _Element {
// int index;
// std::vector<int> tags;
// std::vector<int> connectivity;
// ElementType type;
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_get_nb_nodes_ {
// template <class elem_type> struct result { typedef int type; };
// template <class elem_type> bool operator()(elem_type et) {
// return MeshIOMSH::_msh_nodes_per_elem[et];
// }
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_element_ {
// template <class id_t, class tags_t, class elem_type, class conn_t>
// struct result {
// typedef _Element type;
// };
// template <class id_t, class tags_t, class elem_type, class conn_t>
// _Element operator()(id_t id, const elem_type & et, const tags_t & t,
// const conn_t & c) {
// _Element tmp_el;
// tmp_el.index = id;
// tmp_el.tags = t;
// tmp_el.connectivity = c;
// tmp_el.type = et;
// return tmp_el;
// }
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_check_value_ {
// template <class T> struct result { typedef void type; };
// template <class T> void operator()(T v1, T v2) {
// if (v1 != v2) {
// AKANTU_EXCEPTION("The msh parser expected a "
// << v2 << " in the header bug got a " << v1);
// }
// }
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_node_read_ {
// template <class Mesh, class ID, class V, class size, class Map>
// struct result {
// typedef bool type;
// };
// template <class Mesh, class ID, class V, class size, class Map>
// bool operator()(Mesh & mesh, const ID & id, const V & pos, size max,
// Map & nodes_mapping) const {
// Vector<Real> 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);
// return (mesh.getNbNodes() < UInt(max));
// }
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_element_read_ {
// template <class Mesh, class EL, class size, class NodeMap, class ElemMap>
// struct result {
// typedef bool type;
// };
// template <class Mesh, class EL, class size, class NodeMap, class ElemMap>
// bool operator()(Mesh & mesh, const EL & element, size max,
// const NodeMap & nodes_mapping,
// ElemMap & elements_mapping) const {
// Vector<UInt> tmp_conn(Mesh::getNbNodesPerElement(element.type));
// AKANTU_DEBUG_ASSERT(element.connectivity.size() == tmp_conn.size(),
// "The element "
// << element.index
// << "in the MSH file has too many nodes.");
// mesh.addConnectivityType(element.type);
// Array<UInt> & connectivity = mesh.getConnectivity(element.type);
// UInt i = 0;
// for (std::vector<int>::const_iterator it =
// element.connectivity.begin();
// it != element.connectivity.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;
// }
// ::akantu::Element el(element.type, connectivity.getSize());
// elements_mapping[element.index] = el;
// connectivity.push_back(tmp_conn);
// for (UInt i = 0; i < element.tags.size(); ++i) {
// std::stringstream tag_sstr;
// tag_sstr << "tag_" << i;
// Array<UInt> * data =
// mesh.template getDataPointer<UInt>(tag_sstr.str(), element.type,
// _not_ghost);
// data->push_back(element.tags[i]);
// }
// return (mesh.getNbElement() < UInt(max));
// }
// };
// /* ------------------------------------------------------------------------
// */
// template <class Iterator, typename Skipper = ascii::space_type>
// struct MshMeshGrammar : qi::grammar<Iterator, void(), Skipper> {
// public:
// MshMeshGrammar(Mesh & mesh)
// : MshMeshGrammar::base_type(start, "msh_mesh_reader"), mesh(mesh) {
// phx::function<lazy_element_> lazy_element;
// phx::function<lazy_get_nb_nodes_> lazy_get_nb_nodes;
// phx::function<lazy_check_value_> lazy_check_value;
// phx::function<lazy_node_read_> lazy_node_read;
// phx::function<lazy_element_read_> lazy_element_read;
// clang-format off
// start
// = *( known_section | unknown_section
// )
// ;
// known_section
// = qi::char_("$")
// >> sections [ lbs::_a = lbs::_1 ]
// >> qi::lazy(*lbs::_a)
// >> qi::lit("$End")
// //>> qi::lit(phx::ref(lbs::_a))
// ;
// unknown_section
// = qi::char_("$")
// >> qi::char_("") [ lbs::_a = lbs::_1 ]
// >> ignore_section
// >> qi::lit("$End")
// >> qi::lit(phx::val(lbs::_a))
// ;
// mesh_format // version followed by 0 or 1 for ascii or binary
// = version >> (
// ( qi::char_("0")
// >> qi::int_ [ lazy_check_value(lbs::_1, 8) ]
// )
// | ( qi::char_("1")
// >> qi::int_ [ lazy_check_value(lbs::_1, 8) ]
// >> qi::dword [ lazy_check_value(lbs::_1, 1) ]
// )
// )
// ;
// nodes
// = nodes_
// ;
// nodes_
// = qi::int_ [ lbs::_a = lbs::_1 ]
// > *(
// ( qi::int_ >> position ) [ lazy_node_read(phx::ref(mesh),
// lbs::_1,
// phx::cref(lbs::_2),
// lbs::_a,
// phx::ref(this->msh_nodes_to_akantu)) ]
// )
// ;
// element
// = elements_
// ;
// elements_
// = qi::int_ [ lbs::_a = lbs::_1 ]
// > qi::repeat(phx::ref(lbs::_a))[ element [ lazy_element_read(phx::ref(mesh),
// lbs::_1,
// phx::cref(lbs::_a),
// phx::cref(this->msh_nodes_to_akantu),
// phx::ref(this->msh_elemt_to_akantu)) ]]
// ;
// ignore_section
// = *(qi::char_ - qi::char_('$'))
// ;
// interpolation_scheme = ignore_section;
// element_data = ignore_section;
// node_data = ignore_section;
// version
// = qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ]
// >> *( qi::char_(".") >> qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ] )
// ;
// position
// = real [ phx::push_back(lbs::_val, lbs::_1) ]
// > real [ phx::push_back(lbs::_val, lbs::_1) ]
// > real [ phx::push_back(lbs::_val, lbs::_1) ]
// ;
// tags
// = qi::int_ [ lbs::_a = lbs::_1 ]
// > qi::repeat(phx::val(lbs::_a))[ qi::int_ [ phx::push_back(lbs::_val,
// lbs::_1) ] ]
// ;
// element
// = ( qi::int_ [ lbs::_a = lbs::_1 ]
// > msh_element_type [ lbs::_b = lazy_get_nb_nodes(lbs::_1) ]
// > tags [ lbs::_c = lbs::_1 ]
// > connectivity(lbs::_a) [ lbs::_d = lbs::_1 ]
// ) [ lbs::_val = lazy_element(lbs::_a,
// phx::cref(lbs::_b),
// phx::cref(lbs::_c),
// phx::cref(lbs::_d)) ]
// ;
// connectivity
// = qi::repeat(lbs::_r1)[ qi::int_ [ phx::push_back(lbs::_val,
// lbs::_1) ] ]
// ;
// sections.add
// ("MeshFormat", &mesh_format)
// ("Nodes", &nodes)
// ("Elements", &elements)
// ("PhysicalNames", &physical_names)
// ("InterpolationScheme", &interpolation_scheme)
// ("ElementData", &element_data)
// ("NodeData", &node_data);
// msh_element_type.add
// ("0" , _not_defined )
// ("1" , _segment_2 )
// ("2" , _triangle_3 )
// ("3" , _quadrangle_4 )
// ("4" , _tetrahedron_4 )
// ("5" , _hexahedron_8 )
// ("6" , _pentahedron_6 )
// ("7" , _not_defined )
// ("8" , _segment_3 )
// ("9" , _triangle_6 )
// ("10", _not_defined )
// ("11", _tetrahedron_10)
// ("12", _not_defined )
// ("13", _not_defined )
// ("14", _hexahedron_20 )
// ("15", _pentahedron_15)
// ("16", _not_defined )
// ("17", _point_1 )
// ("18", _quadrangle_8 );
// mesh_format .name("MeshFormat" );
// nodes .name("Nodes" );
// elements .name("Elements" );
// physical_names .name("PhysicalNames" );
// interpolation_scheme.name("InterpolationScheme");
// element_data .name("ElementData" );
// node_data .name("NodeData" );
// clang-format on
// }
// /* ----------------------------------------------------------------------
// */
// /* Rules */
// /* ----------------------------------------------------------------------
// */
// private:
// qi::symbols<char, ElementType> msh_element_type;
// qi::symbols<char, qi::rule<Iterator, void(), Skipper> *> sections;
// qi::rule<Iterator, void(), Skipper> start;
// qi::rule<Iterator, void(), Skipper, qi::locals<std::string> >
// unknown_section;
// qi::rule<Iterator, void(), Skipper, qi::locals<qi::rule<Iterator,
// Skipper> *> > known_section;
// qi::rule<Iterator, void(), Skipper> mesh_format, nodes, elements,
// physical_names, ignore_section,
// interpolation_scheme, element_data, node_data, any_line;
// qi::rule<Iterator, void(), Skipper, qi::locals<int> > nodes_;
// qi::rule<Iterator, void(), Skipper, qi::locals< int, int, vector<int>,
// vector<int> > > elements_;
// qi::rule<Iterator, std::vector<int>(), Skipper> version;
// qi::rule<Iterator, _Element(), Skipper, qi::locals<ElementType> >
// element;
// qi::rule<Iterator, std::vector<int>(), Skipper, qi::locals<int> > tags;
// qi::rule<Iterator, std::vector<int>(int), Skipper> connectivity;
// qi::rule<Iterator, std::vector<Real>(), Skipper> position;
// qi::real_parser<Real, qi::real_policies<Real> > real;
// /* ----------------------------------------------------------------------
// */
// /* Members */
// /* ----------------------------------------------------------------------
// */
// 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<UInt, UInt> msh_nodes_to_akantu;
// /// correspondance between the element number in the abaqus file and the
// /// Element in the akantu mesh
// std::map<UInt, Element> msh_elemt_to_akantu;
// };
// }
// /* --------------------------------------------------------------------------
// */
// void MeshIOAbaqus::read(const std::string& filename, Mesh& mesh) {
// namespace qi = boost::spirit::qi;
// namespace ascii = boost::spirit::ascii;
// 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<char>(infile),
// std::istream_iterator<char>(),
// std::back_inserter(storage));
// typedef std::string::const_iterator iterator_t;
// typedef ascii::space_type skipper;
// typedef _parser::MshMeshGrammar<iterator_t, skipper> grammar;
// grammar g(mesh);
// skipper ws;
// iterator_t iter = storage.begin();
// iterator_t end = storage.end();
// qi::phrase_parse(iter, end, g, ws);
// this->setNbGlobalNodes(mesh, mesh.getNodes().getSize());
// MeshUtils::fillElementToSubElementsData(mesh);
// }
static void my_getline(std::ifstream & infile, std::string & str) {
std::string tmp_str;
std::getline(infile, tmp_str);
str = trim(tmp_str);
}
/* -------------------------------------------------------------------------- */
void MeshIOMSH::read(const std::string & filename, Mesh & mesh) {
std::ifstream infile;
infile.open(filename.c_str());
std::string line;
UInt first_node_number = std::numeric_limits<UInt>::max(),
last_node_number = 0, file_format = 1, current_line = 0;
if (!infile.good()) {
AKANTU_DEBUG_ERROR("Cannot open file " << filename);
}
while (infile.good()) {
my_getline(infile, line);
current_line++;
/// read the header
if (line == "$MeshFormat") {
my_getline(infile, line); /// the format line
std::stringstream sstr(line);
std::string version;
sstr >> version;
Int format;
sstr >> format;
if (format != 0)
AKANTU_DEBUG_ERROR("This reader can only read ASCII files.");
my_getline(infile, line); /// the end of block line
current_line += 2;
file_format = 2;
}
/// read the physical names
if (line == "$PhysicalNames") {
my_getline(infile, line); /// the format line
std::stringstream sstr(line);
UInt num_of_phys_names;
sstr >> num_of_phys_names;
for (UInt k(0); k < num_of_phys_names; k++) {
my_getline(infile, line);
std::stringstream sstr_phys_name(line);
UInt phys_name_id;
UInt phys_dim;
sstr_phys_name >> phys_dim >> phys_name_id;
std::size_t b = line.find("\"");
std::size_t e = line.rfind("\"");
std::string phys_name = line.substr(b + 1, e - b - 1);
phys_name_map[phys_name_id] = phys_name;
}
}
/// read all nodes
if (line == "$Nodes" || line == "$NOD") {
UInt nb_nodes;
my_getline(infile, line);
std::stringstream sstr(line);
sstr >> nb_nodes;
current_line++;
Array<Real> & nodes = const_cast<Array<Real> &>(mesh.getNodes());
nodes.resize(nb_nodes);
mesh.nb_global_nodes = nb_nodes;
UInt index;
Real coord[3];
UInt spatial_dimension = nodes.getNbComponent();
/// for each node, read the coordinates
for (UInt i = 0; i < nb_nodes; ++i) {
UInt offset = i * spatial_dimension;
my_getline(infile, line);
std::stringstream sstr_node(line);
sstr_node >> index >> coord[0] >> coord[1] >> coord[2];
current_line++;
first_node_number = std::min(first_node_number, index);
last_node_number = std::max(last_node_number, index);
/// read the coordinates
for (UInt j = 0; j < spatial_dimension; ++j)
nodes.storage()[offset + j] = coord[j];
}
my_getline(infile, line); /// the end of block line
}
/// read all elements
if (line == "$Elements" || line == "$ELM") {
UInt nb_elements;
std::vector<UInt> read_order;
my_getline(infile, line);
std::stringstream sstr(line);
sstr >> nb_elements;
current_line++;
Int index;
UInt msh_type;
ElementType akantu_type, akantu_type_old = _not_defined;
Array<UInt> * connectivity = NULL;
UInt node_per_element = 0;
for (UInt i = 0; i < nb_elements; ++i) {
my_getline(infile, line);
std::stringstream sstr_elem(line);
current_line++;
sstr_elem >> index;
sstr_elem >> msh_type;
/// get the connectivity vector depending on the element type
akantu_type = this->_msh_to_akantu_element_types[(MSHElementType)msh_type];
if (akantu_type == _not_defined) {
AKANTU_DEBUG_WARNING("Unsuported element kind "
<< msh_type << " at line " << current_line);
continue;
}
if (akantu_type != akantu_type_old) {
connectivity = mesh.getConnectivityPointer(akantu_type);
// connectivity->resize(0);
node_per_element = connectivity->getNbComponent();
akantu_type_old = akantu_type;
read_order = this->_read_order[akantu_type];
}
/// read tags informations
if (file_format == 2) {
UInt nb_tags;
sstr_elem >> nb_tags;
for (UInt j = 0; j < nb_tags; ++j) {
Int tag;
sstr_elem >> tag;
std::stringstream sstr_tag_name;
sstr_tag_name << "tag_" << j;
Array<UInt> * data = mesh.getDataPointer<UInt>(
sstr_tag_name.str(), akantu_type, _not_ghost);
data->push_back(tag);
}
} else if (file_format == 1) {
Int tag;
sstr_elem >> tag; // reg-phys
std::string tag_name = "tag_0";
Array<UInt> * data =
mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
data->push_back(tag);
sstr_elem >> tag; // reg-elem
tag_name = "tag_1";
data = mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
data->push_back(tag);
sstr_elem >> tag; // number-of-nodes
}
UInt local_connect[node_per_element];
for (UInt j = 0; j < node_per_element; ++j) {
UInt node_index;
sstr_elem >> node_index;
AKANTU_DEBUG_ASSERT(node_index <= last_node_number,
"Node number not in range : line "
<< current_line);
node_index -= first_node_number;
local_connect[read_order[j]] = node_index;
}
connectivity->push_back(local_connect);
}
my_getline(infile, line); /// the end of block line
}
if ((line[0] == '$') && (line.find("End") == std::string::npos)) {
AKANTU_DEBUG_WARNING("Unsuported block_kind " << line << " at line "
<< current_line);
}
}
mesh.updateTypesOffsets(_not_ghost);
infile.close();
this->constructPhysicalNames("tag_0", mesh);
MeshUtils::fillElementToSubElementsData(mesh);
}
/* -------------------------------------------------------------------------- */
void MeshIOMSH::write(const std::string & filename, const Mesh & mesh) {
std::ofstream outfile;
const Array<Real> & nodes = mesh.getNodes();
outfile.open(filename.c_str());
outfile << "$MeshFormat" << std::endl;
outfile << "2.1 0 8" << std::endl;
outfile << "$EndMeshFormat" << std::endl;
outfile << std::setprecision(std::numeric_limits<Real>::digits10);
outfile << "$Nodes" << std::endl;
outfile << nodes.getSize() << std::endl;
outfile << std::uppercase;
for (UInt i = 0; i < nodes.getSize(); ++i) {
Int offset = i * nodes.getNbComponent();
outfile << i + 1;
for (UInt j = 0; j < nodes.getNbComponent(); ++j) {
outfile << " " << nodes.storage()[offset + j];
}
for (UInt p = nodes.getNbComponent(); p < 3; ++p)
outfile << " " << 0.;
outfile << std::endl;
;
}
outfile << std::nouppercase;
outfile << "$EndNodes" << std::endl;
;
outfile << "$Elements" << std::endl;
;
Mesh::type_iterator it =
mesh.firstType(_all_dimensions, _not_ghost, _ek_not_defined);
Mesh::type_iterator end =
mesh.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
Int nb_elements = 0;
for (; it != end; ++it) {
const Array<UInt> & connectivity = mesh.getConnectivity(*it, _not_ghost);
nb_elements += connectivity.getSize();
}
outfile << nb_elements << std::endl;
UInt element_idx = 1;
for (it = mesh.firstType(_all_dimensions, _not_ghost, _ek_not_defined);
it != end; ++it) {
ElementType type = *it;
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
UInt * tag[2] = {NULL, NULL};
try {
const Array<UInt> & data_tag_0 =
mesh.getData<UInt>("tag_0", type, _not_ghost);
tag[0] = data_tag_0.storage();
} catch (...) {
tag[0] = NULL;
}
try {
const Array<UInt> & data_tag_1 =
mesh.getData<UInt>("tag_1", type, _not_ghost);
tag[1] = data_tag_1.storage();
} catch (...) {
tag[1] = NULL;
}
for (UInt i = 0; i < connectivity.getSize(); ++i) {
UInt offset = i * connectivity.getNbComponent();
outfile << element_idx << " " << _akantu_to_msh_element_types[type]
<< " 2";
/// \todo write the real data in the file
for (UInt t = 0; t < 2; ++t)
if (tag[t])
outfile << " " << tag[t][i];
else
outfile << " 0";
for (UInt j = 0; j < connectivity.getNbComponent(); ++j) {
outfile << " " << connectivity.storage()[offset + j] + 1;
}
outfile << std::endl;
element_idx++;
}
}
outfile << "$EndElements" << std::endl;
;
outfile.close();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/io/mesh_io/mesh_io_msh.hh b/src/io/mesh_io/mesh_io_msh.hh
index f4656242a..f36eed4e4 100644
--- a/src/io/mesh_io/mesh_io_msh.hh
+++ b/src/io/mesh_io/mesh_io_msh.hh
@@ -1,114 +1,115 @@
/**
* @file mesh_io_msh.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Mon Dec 07 2015
*
* @brief Read/Write for MSH files
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_IO_MSH_HH__
#define __AKANTU_MESH_IO_MSH_HH__
/* -------------------------------------------------------------------------- */
#include "mesh_io.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class MeshIOMSH : public MeshIO {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshIOMSH();
virtual ~MeshIOMSH();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// read a mesh from the file
virtual void read(const std::string & filename, Mesh & mesh);
/// write a mesh to a file
virtual void write(const std::string & filename, const Mesh & mesh);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// MSH element types
enum MSHElementType {
_msh_not_defined = 0,
_msh_segment_2 = 1, // 2-node line.
_msh_triangle_3 = 2, // 3-node triangle.
_msh_quadrangle_4 = 3, // 4-node quadrangle.
_msh_tetrahedron_4 = 4, // 4-node tetrahedron.
_msh_hexahedron_8 = 5, // 8-node hexahedron.
_msh_prism_1 = 6, // 6-node prism.
_msh_pyramid_1 = 7, // 5-node pyramid.
_msh_segment_3 = 8, // 3-node second order line
_msh_triangle_6 = 9, // 6-node second order triangle
_msh_quadrangle_9 = 10, // 9-node second order quadrangle
_msh_tetrahedron_10 = 11, // 10-node second order tetrahedron
_msh_hexahedron_27 = 12, // 27-node second order hexahedron
_msh_prism_18 = 13, // 18-node second order prism
_msh_pyramid_14 = 14, // 14-node second order pyramid
_msh_point = 15, // 1-node point.
_msh_quadrangle_8 = 16, // 8-node second order quadrangle
_msh_hexahedron_20 = 17, // 20-node second order hexahedron
_msh_prism_15 = 18 // 15-node second order prism
};
#define MAX_NUMBER_OF_NODE_PER_ELEMENT 10 // tetrahedron of second order
/// order in witch element as to be read
std::map< ElementType, std::vector<UInt> > _read_order;
/// number of nodes per msh element
std::map<MSHElementType, UInt> _msh_nodes_per_elem;
/// correspondence between msh element types and akantu element types
std::map<MSHElementType, ElementType> _msh_to_akantu_element_types;
/// correspondence between akantu element types and msh element types
std::map<ElementType, MSHElementType> _akantu_to_msh_element_types;
};
__END_AKANTU__
#endif /* __AKANTU_MESH_IO_MSH_HH__ */
diff --git a/src/io/mesh_io/mesh_io_msh_struct.cc b/src/io/mesh_io/mesh_io_msh_struct.cc
index b2861b290..b774895c3 100644
--- a/src/io/mesh_io/mesh_io_msh_struct.cc
+++ b/src/io/mesh_io/mesh_io_msh_struct.cc
@@ -1,79 +1,80 @@
/**
* @file mesh_io_msh_struct.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Jul 15 2011
- * @date last modification: Fri Jul 04 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Mon Dec 07 2015
*
* @brief Read/Write for MSH files generated by gmsh
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "mesh_io.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
MeshIOMSHStruct::MeshIOMSHStruct() : MeshIOMSH() {
canReadSurface = true;
canReadExtendedData = true;
_msh_to_akantu_element_types.clear();
_msh_to_akantu_element_types[_msh_not_defined ] = _not_defined;
_msh_to_akantu_element_types[_msh_segment_2 ] = _bernoulli_beam_2;
_msh_to_akantu_element_types[_msh_triangle_3 ] = _kirchhoff_shell;
_akantu_to_msh_element_types.clear();
_akantu_to_msh_element_types[_not_defined ] = _msh_not_defined;
_akantu_to_msh_element_types[_bernoulli_beam_2] = _msh_segment_2;
_akantu_to_msh_element_types[_bernoulli_beam_3] = _msh_segment_2;
_akantu_to_msh_element_types[_kirchhoff_shell] = _msh_triangle_3;
std::map<ElementType, MSHElementType>::iterator it;
for(it = _akantu_to_msh_element_types.begin();
it != _akantu_to_msh_element_types.end(); ++it) {
UInt nb_nodes = _msh_nodes_per_elem[it->second];
std::vector<UInt> tmp(nb_nodes);
for (UInt i = 0; i < nb_nodes; ++i) tmp[i] = i;
_read_order[it->first] = tmp;
}
}
/* -------------------------------------------------------------------------- */
void MeshIOMSHStruct::read(const std::string & filename, Mesh & mesh) {
if(mesh.getSpatialDimension() == 2) {
_msh_to_akantu_element_types[_msh_segment_2 ] = _bernoulli_beam_2;
} else if (mesh.getSpatialDimension() == 3) {
_msh_to_akantu_element_types[_msh_segment_2 ] = _bernoulli_beam_3;
AKANTU_DEBUG_WARNING("The MeshIOMSHStruct is reading bernoulli beam 3D be sure to provide the missing normals");
}
MeshIOMSH::read(filename, mesh);
}
__END_AKANTU__
diff --git a/src/io/mesh_io/mesh_io_msh_struct.hh b/src/io/mesh_io/mesh_io_msh_struct.hh
index 679680302..698b8e73e 100644
--- a/src/io/mesh_io/mesh_io_msh_struct.hh
+++ b/src/io/mesh_io/mesh_io_msh_struct.hh
@@ -1,55 +1,56 @@
/**
* @file mesh_io_msh_struct.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Jul 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Read/Write for MSH files
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_IO_MSH_STRUCT_HH__
#define __AKANTU_MESH_IO_MSH_STRUCT_HH__
__BEGIN_AKANTU__
class MeshIOMSHStruct : public MeshIOMSH {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshIOMSHStruct();
/// read a mesh from the file
virtual void read(const std::string & filename, Mesh & mesh);
};
__END_AKANTU__
#endif /* __AKANTU_MESH_IO_MSH_STRUCT_HH__ */
diff --git a/src/io/model_io.cc b/src/io/model_io.cc
index 04efb883a..12a2e72d2 100644
--- a/src/io/model_io.cc
+++ b/src/io/model_io.cc
@@ -1,50 +1,50 @@
/**
* @file model_io.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Thu Feb 21 2013
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sun Oct 19 2014
*
- * @brief
+ * @brief Reader for models (this is deprecated)
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "model_io.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
ModelIO::ModelIO() {
}
/* -------------------------------------------------------------------------- */
ModelIO::~ModelIO() {
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/io/model_io.hh b/src/io/model_io.hh
index f95d02142..42892f73e 100644
--- a/src/io/model_io.hh
+++ b/src/io/model_io.hh
@@ -1,81 +1,82 @@
/**
* @file model_io.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Thu Feb 21 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
- * @brief
+ * @brief Reader for models (this is deprecated)
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
#ifndef __AKANTU_MODEL_IO_HH__
#define __AKANTU_MODEL_IO_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "model.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class ModelIO {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ModelIO();
virtual ~ModelIO();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// read a model from file
virtual void read(const std::string & filename, Model & model) = 0;
/// write a mesh to a file
virtual void write(const std::string & filename, const Model & model) = 0;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
__END_AKANTU__
#endif /* __AKANTU_MODEL_IO_HH__ */
diff --git a/src/io/model_io/model_io_ibarras.cc b/src/io/model_io/model_io_ibarras.cc
index 079ef369b..3aa2db6d0 100644
--- a/src/io/model_io/model_io_ibarras.cc
+++ b/src/io/model_io/model_io_ibarras.cc
@@ -1,313 +1,313 @@
/**
* @file model_io_ibarras.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Mesh Reader specially created for Wood's Tower analysis performed by the Institute I-Barras
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "model_io_ibarras.hh"
#include "static_communicator.hh"
#include "aka_math.hh"
#include "static_communicator.hh"
#include "sparse_matrix.hh"
#include "solver.hh"
#include "integration_scheme_2nd_order.hh"
/* -------------------------------------------------------------------------- */
#include <string.h>
/* -------------------------------------------------------------------------- */
#include <stdio.h>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Methods Implentations */
/* -------------------------------------------------------------------------- */
void ModelIOIBarras::read(const std::string & filename, Model & mod) {
if (! dynamic_cast<StructuralMechanicsModel*>(&mod)){
AKANTU_DEBUG_ERROR("");
}
StructuralMechanicsModel & model = static_cast<StructuralMechanicsModel&>(mod);
Mesh * mesh = new Mesh(3);
std::ifstream infile;
infile.open(filename.c_str());
std::string line;
UInt current_line = 0;
if(!infile.good()) {
AKANTU_DEBUG_ERROR("Cannot open file " << filename);
}
// Get Nodes Position
std::getline(infile, line);
current_line++;
std::stringstream sstr(line);
UInt nb_nodes;
sstr >> nb_nodes;
UInt spatial_dimension = 3;
Real coord[spatial_dimension];
Real * temp_nodes = new Real[nb_nodes*spatial_dimension];
UInt * connect_to_akantu = new UInt[nb_nodes];
std::fill_n(connect_to_akantu ,0, nb_nodes);
std::fill_n(temp_nodes ,0., nb_nodes * spatial_dimension);
for (UInt i = 0; i < nb_nodes; ++i) {
UInt offset = i * spatial_dimension;
std::getline(infile, line);
std::stringstream sstr_node(line);
sstr_node >> coord[0] >> coord[1] >> coord[2];
current_line++;
/// read the coordinates of structural nodes and help nodes
for(UInt j = 0; j < spatial_dimension; ++j)
temp_nodes[offset + j] = coord[j];
}
// Get Connectivities
std::getline(infile, line);
current_line++;
std::stringstream sstr_elem(line);
UInt nb_elements;
sstr_elem >> nb_elements;
mesh->addConnectivityType(_bernoulli_beam_3);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(mesh->getConnectivity(_bernoulli_beam_3));
connectivity.resize(nb_elements);
UInt nonodes[2];
UInt nb_struct_nodes=1;
for (UInt i = 0; i < nb_elements; ++i){
std::getline(infile, line);
std::stringstream sstr_element(line);
sstr_element >> nonodes[0] >> nonodes[1];
current_line++;
/// read the connectivities
for(UInt j = 0; j < 2; ++j){
if (connect_to_akantu[nonodes[j]-1]==0){
connect_to_akantu[nonodes[j]-1]=nb_struct_nodes;
++nb_struct_nodes;
}
connectivity(i,j)=connect_to_akantu[nonodes[j]-1]-1;
}
}
nb_struct_nodes-=1;
/// read the coordinates of structural nodes
Array<Real> & nodes = const_cast<Array<Real> &>(mesh->getNodes());
nodes.resize(nb_struct_nodes);
for(UInt k = 0; k < nb_nodes; ++k){
if (connect_to_akantu[k]!=0){
for(UInt j = 0; j < spatial_dimension; ++j)
nodes(connect_to_akantu[k]-1,j) = temp_nodes[k*spatial_dimension+j];
}
}
//MeshPartitionScotch partition(*mesh, spatial_dimension);
//partition.reorder();
///Apply Boundaries
model.registerFEEngineObject<StructuralMechanicsModel::MyFEEngineType>("StructuralMechanicsModel", *mesh, spatial_dimension);
model.initModel();
model.initArrays();
Array<bool> & blocked_dofs = model.getBlockedDOFs();
std::getline(infile, line);
std::stringstream sstr_nb_boundaries(line);
UInt nb_boundaries;
sstr_nb_boundaries >> nb_boundaries;
current_line++;
for (UInt i = 0; i < nb_boundaries; ++i){
std::getline(infile, line);
std::stringstream sstr_boundary(line);
UInt boundnary_node;
sstr_boundary >> boundnary_node;
current_line++;
for (UInt j = 0; j < spatial_dimension; ++j)
blocked_dofs(connect_to_akantu[boundnary_node-1]-1 ,j)=true;
}
///Define Materials
std::getline(infile, line);
std::stringstream sstr_nb_materials(line);
UInt nb_materials;
sstr_nb_materials >> nb_materials;
current_line++;
for (UInt i = 0; i < nb_materials; ++i){
std::getline(infile, line);
std::stringstream sstr_material(line);
Real material[6];
sstr_material >> material[0] >> material[1] >> material[2] >> material[3] >> material[4] >> material[5];
current_line++;
StructuralMaterial mat;
mat.E = material[0];
mat.GJ = material[1] * material[2];
mat.Iy = material[3];
mat.Iz = material[4];
mat.A = material[5];
model.addMaterial(mat);
}
/// Apply normals and Material TO IMPLEMENT
UInt property[2];
Array<UInt> & element_material = model.getElementMaterial(_bernoulli_beam_3);
mesh->initNormals();
Array<Real> & normals = const_cast<Array<Real> &>(mesh->getNormals(_bernoulli_beam_3));
normals.resize(nb_elements);
for (UInt i = 0; i < nb_elements; ++i){
std::getline(infile, line);
std::stringstream sstr_properties(line);
sstr_properties >> property[0] >> property[1];
current_line++;
/// Assign material
element_material(i)=property[0]-1;
/// Compute normals
Real x[3];
Real v[3];
Real w[3];
Real n[3];
if (property[1]==0){
for (UInt j = 0; j < spatial_dimension; ++j){
x[j] = nodes(connectivity(i,1),j) - nodes(connectivity(i,0),j);
}
n[0] = x[1];
n[1] = -x[0];
n[2] = 0.;
}
else{
for (UInt j = 0; j < spatial_dimension; ++j){
x[j] = nodes(connectivity(i,1),j) - nodes(connectivity(i,0),j);
v[j] = nodes(connectivity(i,1),j) - temp_nodes[(property[1]-1) * spatial_dimension + j];
Math::vectorProduct3(x, v, w);
Math::vectorProduct3(x, w, n);
}
}
Math::normalize3(n);
for (UInt j = 0; j < spatial_dimension; ++j){
normals(i,j) = n[j];
}
}
model.computeRotationMatrix(_bernoulli_beam_3);
infile.close();
}
/* -------------------------------------------------------------------------- */
void ModelIOIBarras::assign_sets(const std::string & filename, StructuralMechanicsModel & model){
std::ifstream infile;
infile.open(filename.c_str());
std::string line;
UInt current_line = 0;
if(!infile.good()) {
AKANTU_DEBUG_ERROR("Cannot open file " << filename);
}
// Define Sets of Beams
Array<UInt> & set_ID = model.getSet_ID(_bernoulli_beam_3);
set_ID.clear();
std::getline(infile, line);
std::stringstream sstr_nb_sets(line);
UInt nb_sets;
sstr_nb_sets >> nb_sets;
current_line++;
UInt no_element[2];
for (UInt i = 0; i < nb_sets; ++i){
std::getline(infile, line);
std::stringstream sstr_set(line);
sstr_set >> no_element[0];
no_element[1]=no_element[0];
sstr_set >> no_element[1];
while (no_element[0]!=0) {
for (UInt j = no_element[0]-1 ; j < no_element[1] ; ++j){
set_ID(j) = i+1;
}
std::getline(infile, line);
std::stringstream sstr_sets(line);
sstr_sets >> no_element[0];
no_element[1]=no_element[0];
sstr_sets >> no_element[1];
}
}
}
__END_AKANTU__
diff --git a/src/io/model_io/model_io_ibarras.hh b/src/io/model_io/model_io_ibarras.hh
index 608e12a9e..41023afa9 100644
--- a/src/io/model_io/model_io_ibarras.hh
+++ b/src/io/model_io/model_io_ibarras.hh
@@ -1,69 +1,70 @@
/**
* @file model_io_ibarras.hh
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Thu Feb 21 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief ModelIO implementation for IBarras input files
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MODEL_IO_IBARRAS_HH__
#define __AKANTU_MODEL_IO_IBARRAS_HH__
/* -------------------------------------------------------------------------- */
#include "model_io.hh"
#include "structural_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class ModelIOIBarras : public ModelIO {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ModelIOIBarras(){};
virtual ~ModelIOIBarras(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// read a model from the file
virtual void read(const std::string & filename, Model & model);
/// write a model to a file
virtual void write(const std::string & filename, const Model & model){};
/// assign sets of member to an already constructed model
virtual void assign_sets(const std::string & filename, StructuralMechanicsModel & model);
};
__END_AKANTU__
#endif /* __AKANTU_MODEL_IO_IBARRAS_HH__ */
diff --git a/src/io/parser/algebraic_parser.hh b/src/io/parser/algebraic_parser.hh
index d1545130c..24af4ebee 100644
--- a/src/io/parser/algebraic_parser.hh
+++ b/src/io/parser/algebraic_parser.hh
@@ -1,562 +1,562 @@
/**
* @file algebraic_parser.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Fri May 16 2014
+ * @date last modification: Wed Nov 11 2015
*
* @brief algebraic_parser definition of the grammar
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
// Boost
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#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 <typename, typename, typename>
struct result { typedef void type; };
template <typename Iterator>
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); }
struct lazy_unary_func_ {
template <typename Funct, typename T>
struct result { typedef T type; };
template <typename Funct, typename T>
typename result<Funct, T>::type operator()(Funct f, T a) const {
return f(a);
}
};
struct lazy_binary_func_ {
template <typename Funct, typename T1, typename T2>
struct result { typedef T1 type; };
template <typename Funct, typename T1, typename T2>
typename result<Funct, T1, T2>::type operator()(Funct f, T1 a, T2 b) const {
return f(a, b);
}
};
struct lazy_pow_ {
template <typename T1, typename T2>
struct result { typedef T1 type; };
template <typename T1, typename T2>
typename result<T1, T2>::type operator()(T1 a, T2 b) const {
return std::pow(a, b);
}
};
struct lazy_eval_param_ {
template <typename T1, typename T2, typename res>
struct result { typedef res type; };
template <typename T1, typename T2, typename res>
res operator()(T1 a, const T2 & section,
__attribute__((unused)) const res & result) const {
return section.getParameter(a, _ppsc_current_and_parent_scope);
}
};
template<class Iterator, typename Skipper = spirit::unused_type>
struct AlgebraicGrammar : qi::grammar<Iterator, Real(), Skipper> {
AlgebraicGrammar(const ParserSection & section) : AlgebraicGrammar::base_type(start,
"algebraic_grammar"),
section(section) {
phx::function<algebraic_error_handler_> const error_handler = algebraic_error_handler_();
phx::function<lazy_pow_> lazy_pow;
phx::function<lazy_unary_func_> lazy_unary_func;
phx::function<lazy_binary_func_> lazy_binary_func;
phx::function<lazy_eval_param_> 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
= 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) ]
| (qi::no_case[binary_function]
> '(' >> expr
> ',' >> expr
> ')') [ lbs::_val = lazy_binary_func(lbs::_1, lbs::_2, lbs::_3) ]
;
variable
= key [ lbs::_val = lazy_eval_param(lbs::_1, section, lbs::_val) ]
;
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
;
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
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<Iterator, Real(), Skipper> start;
qi::rule<Iterator, Real(), Skipper> expr;
qi::rule<Iterator, Real(), Skipper> term;
qi::rule<Iterator, Real(), Skipper> factor;
qi::rule<Iterator, Real(), Skipper> number;
qi::rule<Iterator, Real(), Skipper> variable;
qi::rule<Iterator, Real(), Skipper> function;
qi::rule<Iterator, std::string(), Skipper> key;
qi::real_parser< Real, qi::real_policies<Real> > real;
qi::symbols<char, Real> constant;
qi::symbols<char, Real (*) (Real)> unary_function;
qi::symbols<char, Real (*) (Real, Real)> binary_function;
const ParserSection & section;
};
/* ---------------------------------------------------------------------- */
/* Vector Parser */
/* ---------------------------------------------------------------------- */
struct parsable_vector {
operator Vector<Real>() {
Vector<Real> tmp(_cells.size());
std::vector<Real>::iterator it = _cells.begin();
for (UInt i = 0; it != _cells.end(); ++it, ++i) tmp(i) = *it;
return tmp;
}
std::vector<Real> _cells;
};
inline std::ostream& operator<<(std::ostream& stream, const parsable_vector& pv) {
stream << "pv[";
std::vector<Real>::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<Real>() {
size_t cols = 0;
std::vector<parsable_vector>::iterator it_rows = _cells.begin();
for (;it_rows != _cells.end(); ++it_rows) cols = std::max(cols, it_rows->_cells.size());
Matrix<Real> 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<Real>::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<parsable_vector> _cells;
};
inline std::ostream& operator<<(std::ostream& stream, const parsable_matrix& pm) {
stream << "pm[";
std::vector<parsable_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 <typename T1, typename T2>
struct result { typedef void type; };
template <typename T1, typename T2>
void operator()(T1 & cont, T2 & value) const {
cont._cells.push_back(value);
}
};
/* ---------------------------------------------------------------------- */
template<class Iterator, typename Skipper = spirit::unused_type>
struct VectorGrammar : qi::grammar<Iterator, parsable_vector(), Skipper> {
VectorGrammar(const ParserSection & section) : VectorGrammar::base_type(start,
"vector_algebraic_grammar"),
number(section) {
phx::function<algebraic_error_handler_> const error_handler = algebraic_error_handler_();
//phx::function<lazy_algebraic_eval_> lazy_algebraic_eval;
phx::function<lazy_cont_add_> lazy_vector_add;
start
= '[' > vector > ']'
;
vector
= ( number [ lazy_vector_add(lbs::_a, lbs::_1) ]
>> *( ','
>> number [ lazy_vector_add(lbs::_a, lbs::_1) ]
)
) [ lbs::_val = lbs::_a ]
;
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
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<Iterator, parsable_vector(), Skipper> start;
qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper> vector;
qi::rule<Iterator, Real(), Skipper> value;
AlgebraicGrammar<Iterator, Skipper> number;
};
/* ---------------------------------------------------------------------- */
struct lazy_vector_eval_ {
template <typename T1, typename T2, typename res>
struct result { typedef bool type; };
template <typename T1, typename T2, typename res>
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<std::string::const_iterator, qi::space_type> grammar(section);
return qi::phrase_parse(b, e, grammar, qi::space, result);
}
};
/* ---------------------------------------------------------------------- */
template<class Iterator, typename Skipper = spirit::unused_type>
struct MatrixGrammar : qi::grammar<Iterator, parsable_matrix(), Skipper> {
MatrixGrammar(const ParserSection & section) : MatrixGrammar::base_type(start,
"matrix_algebraic_grammar"),
vector(section) {
phx::function<algebraic_error_handler_> const error_handler = algebraic_error_handler_();
phx::function<lazy_vector_eval_> lazy_vector_eval;
phx::function<lazy_cont_add_> lazy_matrix_add;
start
= '[' >> matrix >> ']'
;
matrix
= ( rows [ lazy_matrix_add(lbs::_a, lbs::_1) ]
>> *( ','
>> rows [ lazy_matrix_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
= qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9") // coming from the InputFileGrammar
;
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
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<Iterator, parsable_matrix(), Skipper> start;
qi::rule<Iterator, parsable_matrix(), qi::locals<parsable_matrix>, Skipper> matrix;
qi::rule<Iterator, parsable_vector(), Skipper> rows;
qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper> eval_vector;
qi::rule<Iterator, std::string(), Skipper> key;
VectorGrammar<Iterator, Skipper> 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<class Iterator, typename Skipper = spirit::unused_type>
struct RandomGeneratorGrammar : qi::grammar<Iterator, ParsableRandomGenerator(), Skipper> {
RandomGeneratorGrammar(const ParserSection & section) : RandomGeneratorGrammar::base_type(start,
"random_generator_grammar"),
number(section) {
phx::function<algebraic_error_handler_> const error_handler = algebraic_error_handler_();
phx::function<lazy_cont_add_> lazy_params_add;
start
= generator.alias()
;
generator
= qi::hold[distribution [ lbs::_val = lbs::_1 ] ]
| number [ lbs::_val = phx::construct<ParsableRandomGenerator>(lbs::_1) ]
;
distribution
= (
number
>> generator_type
>> '['
>> generator_params
>> ']'
) [ lbs::_val = phx::construct<ParsableRandomGenerator>(lbs::_1, lbs::_2, lbs::_3) ]
;
generator_params
= ( number [ lazy_params_add(lbs::_a, lbs::_1) ]
>> *( ','
> number [ lazy_params_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
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
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<Iterator, ParsableRandomGenerator(), Skipper> start;
qi::rule<Iterator, ParsableRandomGenerator(), Skipper> generator;
qi::rule<Iterator, ParsableRandomGenerator(), Skipper> distribution;
qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper> generator_params;
AlgebraicGrammar<Iterator, Skipper> number;
qi::symbols<char, RandomDistributionType> generator_type;
};
}
}
#endif /* __AKANTU_ALGEBRAIC_PARSER_HH__ */
diff --git a/src/io/parser/cppargparse/cppargparse.cc b/src/io/parser/cppargparse/cppargparse.cc
index b6544aa02..328d19629 100644
--- a/src/io/parser/cppargparse/cppargparse.cc
+++ b/src/io/parser/cppargparse/cppargparse.cc
@@ -1,471 +1,471 @@
/**
* @file cppargparse.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Apr 03 2014
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Wed Nov 11 2015
*
* @brief implementation of the ArgumentParser
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "cppargparse.hh"
#include <cstdlib>
#include <cstring>
#include <libgen.h>
#include <iostream>
#include <iomanip>
#include <string>
#include <queue>
#include <sstream>
#include <algorithm>
#include <exception>
#include <stdexcept>
#include <string.h>
namespace cppargparse {
/* -------------------------------------------------------------------------- */
static inline std::string to_upper(const std::string & str) {
std::string lstr = str;
std::transform(lstr.begin(),
lstr.end(),
lstr.begin(),
(int(*)(int))std::toupper);
return lstr;
}
/* -------------------------------------------------------------------------- */
/* ArgumentParser */
/* -------------------------------------------------------------------------- */
ArgumentParser::ArgumentParser() : external_exit(NULL), prank(0), psize(1) {
this->addArgument("-h;--help", "show this help message and exit", 0, _boolean, false, true);
}
/* -------------------------------------------------------------------------- */
ArgumentParser::~ArgumentParser() {
for(_Arguments::iterator it = arguments.begin(); it != arguments.end(); ++it) {
delete it->second;
}
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::setParallelContext(int prank, int psize) {
this->prank = prank;
this->psize = psize;
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::_exit(const std::string & msg, int status) {
if(prank == 0) {
if(msg != "") {
std::cerr << msg << std::endl;
std::cerr << std::endl;
}
this->print_help(std::cerr);
}
if(external_exit)
(*external_exit)(status);
else {
exit(status);
}
}
/* -------------------------------------------------------------------------- */
const ArgumentParser::Argument & ArgumentParser::operator[](const std::string & name) const {
Arguments::const_iterator it = success_parsed.find(name);
if(it != success_parsed.end()) {
return *(it->second);
} else {
throw std::range_error("No argument named \'" + name
+ "\' was found in the parsed argument,"
+ " make sur to specify it \'required\'"
+ " or to give it a default value");
}
}
/* -------------------------------------------------------------------------- */
bool ArgumentParser::has(const std::string & name) const
{ return (success_parsed.find(name) != success_parsed.end()); }
/* -------------------------------------------------------------------------- */
void ArgumentParser::addArgument(const std::string & name_or_flag,
const std::string & help,
int nargs,
ArgumentType type) {
_addArgument(name_or_flag, help, nargs, type);
}
/* -------------------------------------------------------------------------- */
ArgumentParser::_Argument & ArgumentParser::_addArgument(const std::string & name,
const std::string & help,
int nargs,
ArgumentType type) {
_Argument * arg = NULL;
switch(type) {
case _string: { arg = new ArgumentStorage<std::string>(); break; }
case _float: { arg = new ArgumentStorage<double>(); break; }
case _integer: { arg = new ArgumentStorage<int>(); break; }
case _boolean: { arg = new ArgumentStorage<bool>(); break; }
}
arg->help = help;
arg->nargs = nargs;
arg->type = type;
std::stringstream sstr(name);
std::string item;
std::vector<std::string> tmp_keys;
while (std::getline(sstr, item, ';')) {
tmp_keys.push_back(item);
}
int long_key = -1;
int short_key = -1;
bool problem = (tmp_keys.size() > 2) || (name == "");
for (std::vector<std::string>::iterator it = tmp_keys.begin(); it != tmp_keys.end(); ++it) {
if(it->find("--") == 0) {
problem |= (long_key != -1);
long_key = it - tmp_keys.begin();
} else if(it->find("-") == 0) {
problem |= (long_key != -1);
short_key = it - tmp_keys.begin();
}
}
problem |= ((tmp_keys.size() == 2) && (long_key == -1 || short_key == -1));
if(problem) {
throw std::invalid_argument("Synthax of name or flags is not correct. Possible synthax are \'-f\', \'-f;--foo\', \'--foo\', \'bar\'");
}
if(long_key != -1) {
arg->name = tmp_keys[long_key];
arg->name.erase(0, 2);
} else if(short_key != -1) {
arg->name = tmp_keys[short_key];
arg->name.erase(0, 1);
} else {
arg->name = tmp_keys[0];
pos_args.push_back(arg);
arg->required = true;
arg->is_positional = true;
}
arguments[arg->name] = arg;
if(!arg->is_positional) {
if(short_key != -1) {
std::string key = tmp_keys[short_key];
key_args[key] = arg;
arg->keys.push_back(key);
}
if(long_key != -1) {
std::string key = tmp_keys[long_key];
key_args[key] = arg;
arg->keys.push_back(key);
}
}
return *arg;
}
#if not HAVE_STRDUP
static char * strdup(const char * str) {
size_t len = strlen(str);
char *x = (char *)malloc(len+1); /* 1 for the null terminator */
if(!x) return NULL; /* malloc could not allocate memory */
memcpy(x,str,len+1); /* copy the string into the new buffer */
return x;
}
#endif
/* -------------------------------------------------------------------------- */
void ArgumentParser::parse(int& argc, char**& argv, int flags, bool parse_help) {
bool stop_in_not_parsed = flags & _stop_on_not_parsed;
bool remove_parsed = flags & _remove_parsed;
std::vector<std::string> argvs;
for (int i = 0; i < argc; ++i) {
argvs.push_back(std::string(argv[i]));
}
unsigned int current_position = 0;
if(this->program_name == "" && argc > 0) {
std::string prog = argvs[current_position];
const char * c_prog = prog.c_str();
char * c_prog_tmp = strdup(c_prog);
std::string base_prog(basename(c_prog_tmp));
this->program_name = base_prog;
std::free(c_prog_tmp);
}
std::queue<_Argument *> positional_queue;
for(PositionalArgument::iterator it = pos_args.begin();
it != pos_args.end(); ++it)
positional_queue.push(*it);
std::vector<int> argvs_to_remove;
++current_position; // consume argv[0]
while(current_position < argvs.size()) {
std::string arg = argvs[current_position];
++current_position;
ArgumentKeyMap::iterator key_it = key_args.find(arg);
bool is_positional = false;
_Argument * argument_ptr = NULL;
if(key_it == key_args.end()) {
if(positional_queue.empty()) {
if(stop_in_not_parsed) this->_exit("Argument " + arg + " not recognized", EXIT_FAILURE);
continue;
} else {
argument_ptr = positional_queue.front();
is_positional = true;
--current_position;
}
} else {
argument_ptr = key_it->second;
}
if(remove_parsed && ! is_positional && argument_ptr->name != "help") {
argvs_to_remove.push_back(current_position - 1);
}
_Argument & argument = *argument_ptr;
unsigned int min_nb_val = 0, max_nb_val = 0;
switch(argument.nargs) {
case _one_if_possible: max_nb_val = 1; break; // "?"
case _at_least_one: min_nb_val = 1; // "+"
case _any: max_nb_val = argc - current_position; break; // "*"
default: min_nb_val = max_nb_val = argument.nargs; // "N"
}
std::vector<std::string> values;
unsigned int arg_consumed = 0;
if(max_nb_val <= (argc - current_position)) {
for(; arg_consumed < max_nb_val; ++arg_consumed) {
std::string v = argvs[current_position];
++current_position;
bool is_key = key_args.find(v) != key_args.end();
bool is_good_type = checkType(argument.type, v);
if(!is_key && is_good_type) {
values.push_back(v);
if(remove_parsed) argvs_to_remove.push_back(current_position - 1);
} else {
// unconsume not parsed argument for optional
if(!is_positional || (is_positional && is_key)) --current_position;
break;
}
}
}
if(arg_consumed < min_nb_val) {
if(!is_positional) {
this->_exit("Not enought values for the argument "
+ argument.name + " where provided", EXIT_FAILURE);
} else {
if(stop_in_not_parsed) this->_exit("Argument " + arg + " not recognized", EXIT_FAILURE);
}
} else {
if (is_positional) positional_queue.pop();
if(!argument.parsed) {
success_parsed[argument.name] = &argument;
argument.parsed = true;
if((argument.nargs == _one_if_possible || argument.nargs == 0) && arg_consumed == 0) {
if(argument.has_const)
argument.setToConst();
else if(argument.has_default)
argument.setToDefault();
} else {
argument.setValues(values);
}
} else {
this->_exit("Argument " + argument.name
+ " already present in the list of argument", EXIT_FAILURE);
}
}
}
for (_Arguments::iterator ait = arguments.begin();
ait != arguments.end(); ++ait) {
_Argument & argument = *(ait->second);
if(!argument.parsed) {
if(argument.has_default) {
argument.setToDefault();
success_parsed[argument.name] = &argument;
}
if(argument.required) {
this->_exit("Argument " + argument.name + " required but not given!", EXIT_FAILURE);
}
}
}
// removing the parsed argument if remove_parsed is true
if(argvs_to_remove.size()) {
std::vector<int>::const_iterator next_to_remove = argvs_to_remove.begin();
for (int i = 0, c = 0; i < argc; ++i) {
if(next_to_remove == argvs_to_remove.end() || i != *next_to_remove) {
argv[c] = argv[i];
++c;
} else {
if (next_to_remove != argvs_to_remove.end()) ++next_to_remove;
}
}
argc -= argvs_to_remove.size();
}
if(this->arguments["help"]->parsed && parse_help) {
this->_exit();
}
}
/* -------------------------------------------------------------------------- */
bool ArgumentParser::checkType(ArgumentType type, const std::string & value) const {
std::stringstream sstr(value);
switch(type) {
case _string: { std::string s; sstr >> s; break; }
case _float: { double d; sstr >> d; break; }
case _integer: { int i; sstr >> i; break; }
case _boolean: { bool b; sstr >> b; break; }
}
return (sstr.fail() == false);
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::printself(std::ostream & stream) const {
for(Arguments::const_iterator it = success_parsed.begin();
it != success_parsed.end(); ++it) {
const Argument & argument = *(it->second);
argument.printself(stream);
stream << std::endl;
}
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::print_usage(std::ostream & stream) const {
stream << "Usage: " << this->program_name;
std::stringstream sstr_opt;
// print shorten usage
for(_Arguments::const_iterator it = arguments.begin();
it != arguments.end(); ++it) {
const _Argument & argument = *(it->second);
if(!argument.is_positional) {
if(!argument.required) stream << " [";
stream << argument.keys[0];
this->print_usage_nargs(stream, argument);
if(!argument.required) stream << "]";
}
}
for(PositionalArgument::const_iterator it = pos_args.begin();
it != pos_args.end(); ++it) {
const _Argument & argument = **it;
this->print_usage_nargs(stream, argument);
}
stream << std::endl;
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::print_usage_nargs(std::ostream & stream,
const _Argument & argument) const {
std::string u_name = to_upper(argument.name);
switch(argument.nargs) {
case _one_if_possible: stream << " [" << u_name << "]"; break;
case _at_least_one: stream << " " << u_name;
case _any: stream << " [" << u_name << " ...]"; break;
default:
for(int i = 0; i < argument.nargs; ++i) {
stream << " " << u_name;
}
}
}
void ArgumentParser::print_help(std::ostream & stream) const {
this->print_usage(stream);
if(!pos_args.empty()) {
stream << std::endl;
stream << "positional arguments:" << std::endl;
for(PositionalArgument::const_iterator it = pos_args.begin();
it != pos_args.end(); ++it) {
const _Argument & argument = **it;
this->print_help_argument(stream, argument);
}
}
if(!key_args.empty()) {
stream << std::endl;
stream << "optional arguments:" << std::endl;
for(_Arguments::const_iterator it = arguments.begin();
it != arguments.end(); ++it) {
const _Argument & argument = *(it->second);
if(!argument.is_positional) {
this->print_help_argument(stream, argument);
}
}
}
}
void ArgumentParser::print_help_argument(std::ostream & stream, const _Argument & argument) const {
std::string key("");
if(argument.is_positional)
key = argument.name;
else {
std::stringstream sstr;
for(unsigned int i = 0; i < argument.keys.size(); ++i) {
if(i != 0) sstr << ", ";
sstr << argument.keys[i];
this->print_usage_nargs(sstr, argument);
}
key = sstr.str();
}
stream << " " << std::left << std::setw(15) << key << " " << argument.help;
argument.printDefault(stream);
stream << std::endl;
}
}
diff --git a/src/io/parser/cppargparse/cppargparse.hh b/src/io/parser/cppargparse/cppargparse.hh
index 9db3b0b27..74a9592cf 100644
--- a/src/io/parser/cppargparse/cppargparse.hh
+++ b/src/io/parser/cppargparse/cppargparse.hh
@@ -1,185 +1,185 @@
/**
* @file cppargparse.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Apr 03 2014
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief Get the commandline options and store them as short, long and others
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <map>
#include <string>
#include <iostream>
#include <vector>
#ifndef __CPPARGPARSE_HH__
#define __CPPARGPARSE_HH__
namespace cppargparse {
/// define the types of the arguments
enum ArgumentType { _string, _integer, _float, _boolean };
/// Defines how many arguments to expect
enum ArgumentNargs { _one_if_possible = -1, _at_least_one = -2, _any = -3 };
/// Flags for the parse function of ArgumentParser
enum ParseFlags {
_no_flags = 0x0, ///< Default behavior
_stop_on_not_parsed = 0x1, ///< Stop on unknown arguments
_remove_parsed = 0x2 ///< Remove parsed arguments from argc argv
};
/// Helps to combine parse flags
inline ParseFlags operator|(const ParseFlags & a, const ParseFlags & b) {
ParseFlags tmp = ParseFlags(int(a) | int(b));
return tmp;
}
/**
* ArgumentParser is a class that mimics the Python argparse module
*/
class ArgumentParser {
public:
/// public definition of an argument
class Argument {
public:
Argument() : name(std::string()) {}
virtual ~Argument() {}
virtual void printself(std::ostream & stream) const = 0;
template <class T> operator T() const;
std::string name;
};
/// constructor
ArgumentParser();
/// destroy everything
~ArgumentParser();
/// add an argument with a description
void addArgument(const std::string & name_or_flag, const std::string & help,
int nargs = 1, ArgumentType type = _string);
/// add an argument with an help and a default value
template <class T>
void addArgument(const std::string & name_or_flag, const std::string & help,
int nargs, ArgumentType type, T def);
/// add an argument with an help and a default + const value
template <class T>
void addArgument(const std::string & name_or_flag, const std::string & help,
int nargs, ArgumentType type, T def, T cons);
/// parse argc, argv
void parse(int & argc, char **& argv, int flags = _stop_on_not_parsed,
bool parse_help = true);
/// print the content in the stream
void printself(std::ostream & stream) const;
/// print the help text
void print_help(std::ostream & stream = std::cout) const;
/// print the usage text
void print_usage(std::ostream & stream = std::cout) const;
/// set an external function to replace the exit function from the stdlib
void setExternalExitFunction(void (*external_exit)(int)) {
this->external_exit = external_exit;
}
/// accessor for a registered argument that was parsed, throw an exception if
/// the argument does not exist or was not set (parsed or default value)
const Argument & operator[](const std::string & name) const;
bool has(const std::string &) const;
/// set the parallel context to avoid multiple help messages in
/// multiproc/thread cases
void setParallelContext(int prank, int psize);
public:
/// Internal class describing the arguments
struct _Argument;
/// Stores that value of an argument
template<class T> class ArgumentStorage;
private:
/// Internal function to be used by the public addArgument
_Argument & _addArgument(const std::string & name_or_flag,
const std::string & description, int nargs,
ArgumentType type);
void _exit(const std::string & msg = "", int status = 0);
bool checkType(ArgumentType type, const std::string & value) const;
/// function to help to print help
void print_usage_nargs(std::ostream & stream,
const _Argument & argument) const;
/// function to help to print help
void print_help_argument(std::ostream & stream,
const _Argument & argument) const;
private:
/// public arguments storage
typedef std::map<std::string, Argument *> Arguments;
/// internal arguments storage
typedef std::map<std::string, _Argument *> _Arguments;
/// association key argument
typedef std::map<std::string, _Argument *> ArgumentKeyMap;
/// position arguments
typedef std::vector<_Argument *> PositionalArgument;
/// internal storage of arguments declared by the user
_Arguments arguments;
/// list of arguments successfully parsed
Arguments success_parsed;
/// keys associated to arguments
ArgumentKeyMap key_args;
/// positional arguments
PositionalArgument pos_args;
/// argv[0]
std::string program_name;
/// exit function to use
void (*external_exit)(int);
/// parallel context
int prank, psize;
};
}
inline std::ostream & operator<<(std::ostream & stream,
const cppargparse::ArgumentParser & argparse) {
argparse.printself(stream);
return stream;
}
#endif /* __CPPARGPARSE_HH__ */
#include "cppargparse_tmpl.hh"
diff --git a/src/io/parser/cppargparse/cppargparse_tmpl.hh b/src/io/parser/cppargparse/cppargparse_tmpl.hh
index c11e97294..92a662404 100644
--- a/src/io/parser/cppargparse/cppargparse_tmpl.hh
+++ b/src/io/parser/cppargparse/cppargparse_tmpl.hh
@@ -1,245 +1,245 @@
/**
* @file cppargparse_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Apr 03 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief Implementation of the templated part of the commandline argument
* parser
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <stdexcept>
#include <sstream>
#ifndef __CPPARGPARSE_TMPL_HH__
#define __CPPARGPARSE_TMPL_HH__
namespace cppargparse {
/* -------------------------------------------------------------------------- */
/* Argument */
/* -------------------------------------------------------------------------- */
/// internal description of arguments
struct ArgumentParser::_Argument : public Argument {
_Argument()
: Argument(), help(std::string()), nargs(1), type(_string),
required(false), parsed(false), has_default(false), has_const(false),
is_positional(false) {}
virtual ~_Argument() {}
void setValues(std::vector<std::string> & values) {
for (std::vector<std::string>::iterator it = values.begin();
it != values.end(); ++it) {
this->addValue(*it);
}
}
virtual void addValue(std::string & value) = 0;
virtual void setToDefault() = 0;
virtual void setToConst() = 0;
std::ostream & printDefault(std::ostream & stream) const {
stream << std::boolalpha;
if (has_default) {
stream << " (default: ";
this->_printDefault(stream);
stream << ")";
}
if (has_const) {
stream << " (const: ";
this->_printConst(stream);
stream << ")";
}
return stream;
}
virtual std::ostream & _printDefault(std::ostream & stream) const = 0;
virtual std::ostream & _printConst(std::ostream & stream) const = 0;
std::string help;
int nargs;
ArgumentType type;
bool required;
bool parsed;
bool has_default;
bool has_const;
std::vector<std::string> keys;
bool is_positional;
};
/* -------------------------------------------------------------------------- */
/// typed storage of the arguments
template <class T>
class ArgumentParser::ArgumentStorage : public ArgumentParser::_Argument {
public:
ArgumentStorage() : _default(T()), _const(T()), values(std::vector<T>()) {}
virtual void addValue(std::string & value) {
std::stringstream sstr(value);
T t;
sstr >> t;
values.push_back(t);
}
virtual void setToDefault() {
values.clear();
values.push_back(_default);
}
virtual void setToConst() {
values.clear();
values.push_back(_const);
}
void printself(std::ostream & stream) const {
stream << this->name << " =";
stream << std::boolalpha; // for boolean
for (typename std::vector<T>::const_iterator vit = this->values.begin();
vit != this->values.end(); ++vit) {
stream << " " << *vit;
}
}
virtual std::ostream & _printDefault(std::ostream & stream) const {
stream << _default;
return stream;
}
virtual std::ostream & _printConst(std::ostream & stream) const {
stream << _const;
return stream;
}
T _default;
T _const;
std::vector<T> values;
};
/* -------------------------------------------------------------------------- */
template <>
inline void
ArgumentParser::ArgumentStorage<std::string>::addValue(std::string & value) {
values.push_back(value);
}
template <class T> struct is_vector {
enum { value = false };
};
template <class T> struct is_vector<std::vector<T> > {
enum { value = true };
};
/* -------------------------------------------------------------------------- */
template <class T, bool is_vector = cppargparse::is_vector<T>::value>
struct cast_helper {
static T cast(const ArgumentParser::Argument & arg) {
const ArgumentParser::ArgumentStorage<T> & _arg =
dynamic_cast<const ArgumentParser::ArgumentStorage<T> &>(arg);
if (_arg.values.size() == 1) {
return _arg.values[0];
} else {
throw std::length_error("Not enougth or too many argument where passed "
"for the command line argument: " +
arg.name);
}
}
};
template <class T> struct cast_helper<T, true> {
static T cast(const ArgumentParser::Argument & arg) {
const ArgumentParser::ArgumentStorage<T> & _arg =
dynamic_cast<const ArgumentParser::ArgumentStorage<T> &>(arg);
return _arg.values;
}
};
/* -------------------------------------------------------------------------- */
template <class T> ArgumentParser::Argument::operator T() const {
return cast_helper<T>::cast(*this);
}
template <> inline ArgumentParser::Argument::operator const char *() const {
return cast_helper<std::string>::cast(*this).c_str();
}
template <> inline ArgumentParser::Argument::operator unsigned int() const {
return cast_helper<int>::cast(*this);
}
template <class T>
void ArgumentParser::addArgument(const std::string & name_or_flag,
const std::string & help, int nargs,
ArgumentType type, T def) {
_Argument & arg = _addArgument(name_or_flag, help, nargs, type);
dynamic_cast<ArgumentStorage<T> &>(arg)._default = def;
arg.has_default = true;
}
template <class T>
void ArgumentParser::addArgument(const std::string & name_or_flag,
const std::string & help, int nargs,
ArgumentType type, T def, T cons) {
_Argument & arg = _addArgument(name_or_flag, help, nargs, type);
dynamic_cast<ArgumentStorage<T> &>(arg)._default = def;
arg.has_default = true;
dynamic_cast<ArgumentStorage<T> &>(arg)._const = cons;
arg.has_const = true;
}
/* -------------------------------------------------------------------------- */
template <>
inline void
ArgumentParser::addArgument<const char *>(const std::string & name_or_flag,
const std::string & help, int nargs,
ArgumentType type, const char * def) {
this->addArgument<std::string>(name_or_flag, help, nargs, type, def);
}
template <>
inline void
ArgumentParser::addArgument<unsigned int>(const std::string & name_or_flag,
const std::string & help, int nargs,
ArgumentType type, unsigned int def) {
this->addArgument<int>(name_or_flag, help, nargs, type, def);
}
/* -------------------------------------------------------------------------- */
template <>
inline void ArgumentParser::addArgument<const char *>(
const std::string & name_or_flag, const std::string & help, int nargs,
ArgumentType type, const char * def, const char * cons) {
this->addArgument<std::string>(name_or_flag, help, nargs, type, def, cons);
}
template <>
inline void ArgumentParser::addArgument<unsigned int>(
const std::string & name_or_flag, const std::string & help, int nargs,
ArgumentType type, unsigned int def, unsigned int cons) {
this->addArgument<int>(name_or_flag, help, nargs, type, def, cons);
}
}
#endif /* __AKANTU_CPPARGPARSE_TMPL_HH__ */
diff --git a/src/io/parser/input_file_parser.hh b/src/io/parser/input_file_parser.hh
index 81eb05690..55abfec09 100644
--- a/src/io/parser/input_file_parser.hh
+++ b/src/io/parser/input_file_parser.hh
@@ -1,287 +1,287 @@
/**
* @file input_file_parser.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Fri Apr 04 2014
+ * @date last modification: Tue May 19 2015
*
* @brief Grammar definition for the input files
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
// Boost
/* -------------------------------------------------------------------------- */
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
//#include <boost/foreach.hpp>
#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 <typename, typename, typename, typename>
struct result { typedef void type; };
template <typename Iterator>
void operator()(qi::info const& what,
Iterator err_pos,
Iterator first,
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 lazy_create_subsection_ {
template<typename, typename, typename, typename>
struct result { typedef ParserSection& type; };
template<typename T>
ParserSection& operator()(const SectionType & type, const std::string & name,
const T & option,
ParserSection & sect) const {
std::string opt;
if(option) opt = *option;
ParserSection sect_tmp(name, type, opt, sect);
return sect.addSubSection(sect_tmp);
}
};
template<typename Iterator>
struct lazy_create_parameter_ {
lazy_create_parameter_(std::string & error_message) : error_message(error_message) {}
template<typename, typename, typename>
struct result { typedef bool type; };
template<typename Range>
bool operator()(const Range & rng,
const std::string & value,
ParserSection & sect) const {
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<class T1, class T2>
struct result { typedef T1 type; };
template<class T1, class T2>
T1 operator()(const T1 & t1, const T2 & t2) const {
return (t1 + t2);
}
};
/* ---------------------------------------------------------------------- */
/* Grammars definitions */
/* ---------------------------------------------------------------------- */
template<class Iterator>
struct InputFileGrammar : qi::grammar<Iterator, void(),
typename Skipper<Iterator>::type> {
InputFileGrammar(ParserSection * sect) : InputFileGrammar::base_type(start,
"input_file_grammar"),
parent_section(sect) {
phx::function<error_handler_> const error_handler = error_handler_();
phx::function< lazy_create_parameter_<Iterator> > lazy_create_parameter
= lazy_create_parameter_<Iterator>(error_message);
phx::function<lazy_create_subsection_> lazy_create_subsection;
phx::function<lazy_concatenate_> lazy_concatenate;
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) ]
;
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) ]
> '['
> 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 = lazy_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)
;
#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
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_1, lbs::_2));
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<Iterator>::type skipper_type;
skipper_type skipper;
private:
std::string error_message;
qi::rule<Iterator, void(ParserSection *), skipper_type> mini_section;
qi::rule<Iterator, void(ParserSection *), qi::locals<ParserSection *>, skipper_type> section;
qi::rule<Iterator, void() , skipper_type> start;
qi::rule<Iterator, std::string() > section_name;
qi::rule<Iterator, std::string() > section_option;
qi::rule<Iterator, void(ParserSection *), skipper_type> entry;
qi::rule<Iterator, std::string() , skipper_type> key;
qi::rule<Iterator, std::string() , qi::locals<std::string>, skipper_type> value;
qi::rule<Iterator, std::string() , skipper_type> mono_line_value;
qi::symbols<char, SectionType> section_type;
ParserSection * parent_section;
};
}
__END_AKANTU__
#endif /* __AKANTU_INPUT_FILE_PARSER_HH__ */
diff --git a/src/io/parser/parsable.cc b/src/io/parser/parsable.cc
index 3ffd75688..726986f0a 100644
--- a/src/io/parser/parsable.cc
+++ b/src/io/parser/parsable.cc
@@ -1,195 +1,195 @@
/**
* @file parsable.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Thu Nov 19 2015
*
* @brief Parsable implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "parsable.hh"
#include "aka_random_generator.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
ParsableParam::ParsableParam(): name(""), description(""), param_type(_pat_internal) { }
/* -------------------------------------------------------------------------- */
ParsableParam::ParsableParam(std::string name, std::string description,
ParamAccessType param_type) :
name(name),
description(description),
param_type(param_type) {
}
/* -------------------------------------------------------------------------- */
bool ParsableParam::isWritable() const { return param_type & _pat_writable; }
/* -------------------------------------------------------------------------- */
bool ParsableParam::isReadable() const { return param_type & _pat_readable; }
/* -------------------------------------------------------------------------- */
bool ParsableParam::isInternal() const { return param_type & _pat_internal; }
/* -------------------------------------------------------------------------- */
bool ParsableParam::isParsable() const { return param_type & _pat_parsable; }
/* -------------------------------------------------------------------------- */
void ParsableParam::setAccessType(ParamAccessType ptype) {
this->param_type = ptype;
}
/* -------------------------------------------------------------------------- */
void ParsableParam::printself(std::ostream & stream) const {
stream << " ";
if(isInternal()) stream << "iii";
else {
if(isReadable()) stream << "r";
else stream << "-";
if(isWritable()) stream << "w";
else stream << "-";
if(isParsable()) stream << "p";
else stream << "-";
}
stream << " ";
std::stringstream sstr;
sstr << name;
UInt width = std::max(int(10 - sstr.str().length()), 0);
sstr.width(width);
if(description != "") {
sstr << " [" << description << "]";
}
stream << sstr.str();
width = std::max(int(50 - sstr.str().length()), 0);
stream.width(width);
stream << " : ";
}
/* -------------------------------------------------------------------------- */
void ParsableParam::parseParam(const ParserParameter & param) {
if(!isParsable()) AKANTU_EXCEPTION("The parameter named " << param.getName() << " is not parsable.");
}
/* -------------------------------------------------------------------------- */
Parsable::~Parsable() {
std::map<std::string, ParsableParam *>::iterator it, end;
for(it = params.begin(); it != params.end(); ++it){
delete it->second;
it->second = NULL;
}
this->params.clear();
}
/* -------------------------------------------------------------------------- */
void Parsable::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
std::map<std::string, ParsableParam *>::const_iterator it, end;
for(it = params.begin(); it != params.end(); ++it){
stream << space;
it->second->printself(stream);
}
SubSections::const_iterator sit, send;
for(sit = sub_sections.begin(); sit != sub_sections.end(); ++sit) {
sit->second->printself(stream, indent + 1);
}
}
/* -------------------------------------------------------------------------- */
void Parsable::setParamAccessType(const std::string & name, ParamAccessType ptype) {
std::map<std::string, ParsableParam *>::iterator it = params.find(name);
if(it == params.end()) AKANTU_EXCEPTION("No parameter named " << name << " in parsable.");
ParsableParam & param = *(it->second);
param.setAccessType(ptype);
}
/* -------------------------------------------------------------------------- */
void Parsable::registerSubSection(const SectionType & type,
const std::string & name,
Parsable & sub_section) {
SubSectionKey key(type, name);
sub_sections[key] = &sub_section;
}
/* -------------------------------------------------------------------------- */
void Parsable::parseParam(const ParserParameter & in_param) {
std::map<std::string, ParsableParam *>::iterator it = params.find(in_param.getName());
if(it == params.end()) {
if(Parser::isPermissive()) {
AKANTU_DEBUG_WARNING("No parameter named " << in_param.getName()
<< " registered in " << pid << ".");
return;
} else AKANTU_EXCEPTION("No parameter named " << in_param.getName()
<< " registered in " << pid << ".");
}
ParsableParam & param = *(it->second);
param.parseParam(in_param);
}
/* -------------------------------------------------------------------------- */
void Parsable::parseSection(const ParserSection & section) {
if(section_type != section.getType())
AKANTU_EXCEPTION("The object " << pid
<< " is meant to parse section of type " << section_type
<< ", so it cannot parse section of type " << section.getType());
std::pair<Parser::const_parameter_iterator, Parser::const_parameter_iterator>
params = section.getParameters();
Parser::const_parameter_iterator it = params.first;
for (; it != params.second; ++it) {
parseParam(*it);
}
Parser::const_section_iterator sit = section.getSubSections().first;
for (; sit != section.getSubSections().second; ++sit) {
parseSubSection(*sit);
}
}
/* -------------------------------------------------------------------------- */
void Parsable::parseSubSection(const ParserSection & section) {
SubSectionKey key(section.getType(), section.getName());
SubSections::iterator it = sub_sections.find(key);
if(it != sub_sections.end()) {
it->second->parseSection(section);
} else if(!Parser::isPermissive()) {
AKANTU_EXCEPTION("No parsable defined for sub sections of type <"
<< key.first << "," << key.second << "> in " << pid);
} else AKANTU_DEBUG_WARNING("No parsable defined for sub sections of type <"
<< key.first << "," << key.second << "> in " << pid);
}
__END_AKANTU__
diff --git a/src/io/parser/parsable.hh b/src/io/parser/parsable.hh
index ac05a188e..ecd981471 100644
--- a/src/io/parser/parsable.hh
+++ b/src/io/parser/parsable.hh
@@ -1,203 +1,204 @@
/**
* @file parsable.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Jun 24 2014
+ * @date creation: Thu Aug 09 2012
+ * @date last modification: Thu Dec 17 2015
*
* @brief Interface of parsable objects
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "parser.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PARSABLE_HH__
#define __AKANTU_PARSABLE_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/// Defines the access modes of parsable parameters
enum ParamAccessType {
_pat_internal = 0x0001,
_pat_writable = 0x0010,
_pat_readable = 0x0100,
_pat_modifiable = 0x0110, //_pat_readable | _pat_writable,
_pat_parsable = 0x1000,
_pat_parsmod = 0x1110 //< _pat_parsable | _pat_modifiable
};
/// Bit-wise operator between access modes
inline ParamAccessType operator|(const ParamAccessType & a, const ParamAccessType & b) {
ParamAccessType tmp = ParamAccessType(UInt(a) | UInt(b));
return tmp;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<typename T> class ParsableParamTyped;
/* -------------------------------------------------------------------------- */
/**
* Interface for the ParsableParamTyped
*/
class ParsableParam {
public:
ParsableParam();
ParsableParam(std::string name, std::string description, ParamAccessType param_type);
virtual ~ParsableParam() {};
/* ------------------------------------------------------------------------ */
bool isInternal() const;
bool isWritable() const;
bool isReadable() const;
bool isParsable() const;
void setAccessType(ParamAccessType ptype);
/* ------------------------------------------------------------------------ */
template<typename T, typename V> void set(const V & value);
template<typename T> T & get();
template<typename T> const T & get() const;
virtual void parseParam(const ParserParameter & param);
/* ------------------------------------------------------------------------ */
virtual void printself(std::ostream & stream) const;
protected:
/// Returns const instance of templated sub-class ParsableParamTyped
template<typename T>
const ParsableParamTyped<T> & getParsableParamTyped() const;
/// Returns instance of templated sub-class ParsableParamTyped
template<typename T>
ParsableParamTyped<T> & getParsableParamTyped();
private:
/// Name of parameter
std::string name;
/// Description of parameter
std::string description;
/// Type of access
ParamAccessType param_type;
};
/* -------------------------------------------------------------------------- */
/* Typed Parameter */
/* -------------------------------------------------------------------------- */
/**
* Type parameter transfering a ParserParameter (string: string) to a typed parameter in the memory of the p
*/
template<typename T>
class ParsableParamTyped : public ParsableParam {
public:
ParsableParamTyped(std::string name, std::string description,
ParamAccessType param_type, T & param);
/* ------------------------------------------------------------------------ */
template<typename V>
void setTyped(const V & value);
T & getTyped();
const T & getTyped() const;
void parseParam(const ParserParameter & param);
virtual void printself(std::ostream & stream) const;
private:
/// Value of parameter
T & param;
};
/* -------------------------------------------------------------------------- */
/* Parsable Interface */
/* -------------------------------------------------------------------------- */
/// Defines interface for classes to manipulate parsable parameters
class Parsable {
public:
Parsable(const SectionType & section_type,
const ID & id = std::string()) : section_type(section_type), pid(id) {};
virtual ~Parsable();
/* ------------------------------------------------------------------------ */
/// Add parameter to the params map
template<typename T>
void registerParam(std::string name, T & variable,
ParamAccessType type,
const std::string description = "");
/// Add parameter to the params map (with default value)
template<typename T>
void registerParam(std::string name, T & variable, T default_value,
ParamAccessType type,
const std::string description = "");
/// Add subsection to the sub_sections map
void registerSubSection(const SectionType & type,
const std::string & name,
Parsable & sub_section);
/* ------------------------------------------------------------------------ */
/// Set value to a parameter (with possible different type)
template<typename T, typename V> void setMixed(const std::string & name, const V & value);
/// Set value to a parameter
template<typename T> void set(const std::string & name, const T & value);
/// Get value of a parameter
template<typename T> const T & get(const std::string & name) const;
protected:
template<typename T> T & get(const std::string & name);
protected:
void setParamAccessType(const std::string & name, ParamAccessType ptype);
/* ------------------------------------------------------------------------ */
public:
virtual void parseSection(const ParserSection & section);
virtual void parseSubSection(const ParserSection & section);
virtual void parseParam(const ParserParameter & parameter);
/* ------------------------------------------------------------------------ */
virtual void printself(std::ostream & stream, int indent) const;
private:
SectionType section_type;
/// ID of parsable object
ID pid;
/// Parameters map
std::map<std::string, ParsableParam *> params;
typedef std::pair<SectionType, std::string> SubSectionKey;
typedef std::map<SubSectionKey, Parsable *> SubSections;
/// Subsections map
SubSections sub_sections;
};
__END_AKANTU__
#include "parsable_tmpl.hh"
#endif /* __AKANTU_PARSABLE_HH__ */
diff --git a/src/io/parser/parsable_tmpl.hh b/src/io/parser/parsable_tmpl.hh
index e6afc79c4..8fea0b0a7 100644
--- a/src/io/parser/parsable_tmpl.hh
+++ b/src/io/parser/parsable_tmpl.hh
@@ -1,210 +1,211 @@
/**
* @file parsable_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Jun 24 2014
+ * @date creation: Thu Aug 09 2012
+ * @date last modification: Fri Mar 27 2015
*
* @brief implementation of the templated part of ParsableParam Parsable and
* ParsableParamTyped
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<typename T>
const ParsableParamTyped<T> & ParsableParam::getParsableParamTyped() const {
try {
const ParsableParamTyped<T> & tmp = dynamic_cast<const ParsableParamTyped<T> &>(*this);
return tmp;
} catch (...) {
AKANTU_EXCEPTION("The parameter named " << name << " is of type "
<< debug::demangle(typeid(T).name()) <<".");
}
}
/* -------------------------------------------------------------------------- */
template<typename T>
ParsableParamTyped<T> & ParsableParam::getParsableParamTyped() {
try {
ParsableParamTyped<T> & tmp = dynamic_cast<ParsableParamTyped<T> &>(*this);
return tmp;
} catch (...) {
AKANTU_EXCEPTION("The parameter named " << name << " is of type "
<< debug::demangle(typeid(T).name()) <<".");
}
}
/* ------------------------------------------------------------------------ */
template<typename T, typename V>
void ParsableParam::set(const V & value) {
ParsableParamTyped<T> & typed_param = getParsableParamTyped<T>();
if(!(isWritable())) AKANTU_EXCEPTION("The parameter named " << name << " is not writable.");
typed_param.setTyped(value);
}
/* -------------------------------------------------------------------------- */
template<typename T>
const T & ParsableParam::get() const {
const ParsableParamTyped<T> & typed_param = getParsableParamTyped<T>();
if(!(isReadable())) AKANTU_EXCEPTION("The parameter named " << name << " is not readable.");
return typed_param.getTyped();
}
/* -------------------------------------------------------------------------- */
template<typename T>
T & ParsableParam::get() {
ParsableParamTyped<T> & typed_param = getParsableParamTyped<T>();
if(!(isReadable())) AKANTU_EXCEPTION("The parameter named " << name << " is not readable.");
return typed_param.getTyped();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<typename T>
ParsableParamTyped<T>::ParsableParamTyped(std::string name, std::string description,
ParamAccessType param_type, T & param) :
ParsableParam(name, description, param_type), param(param) {}
/* -------------------------------------------------------------------------- */
template<typename T>
template<typename V>
void ParsableParamTyped<T>::setTyped(const V & value) { param = value; }
/* -------------------------------------------------------------------------- */
template<typename T>
const T & ParsableParamTyped<T>::getTyped() const { return param; }
/* -------------------------------------------------------------------------- */
template<typename T>
T & ParsableParamTyped<T>::getTyped() { return param; }
/* -------------------------------------------------------------------------- */
template<typename T>
inline void ParsableParamTyped<T>::parseParam(const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
param = static_cast<T>(in_param);
}
/* -------------------------------------------------------------------------- */
template<>
inline void ParsableParamTyped< Vector<Real> >::parseParam(const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
Vector<Real> tmp = in_param;
for (UInt i = 0; i < param.size(); ++i) {
param(i) = tmp(i);
}
}
/* -------------------------------------------------------------------------- */
template<>
inline void ParsableParamTyped< Matrix<Real> >::parseParam(const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
Matrix<Real> tmp = in_param;
for (UInt i = 0; i < param.rows(); ++i) {
for (UInt j = 0; j < param.cols(); ++j) {
param(i, j) = tmp(i, j);
}
}
}
/* -------------------------------------------------------------------------- */
template<>
inline void ParsableParamTyped<std::string>::parseParam(const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
param = in_param.getValue();
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void ParsableParamTyped<T>::printself(std::ostream & stream) const {
ParsableParam::printself(stream);
stream << param << std::endl;
}
/* -------------------------------------------------------------------------- */
template<>
inline void ParsableParamTyped<bool>::printself(std::ostream & stream) const {
ParsableParam::printself(stream);
stream << std::boolalpha << param << std::endl;
}
/* -------------------------------------------------------------------------- */
template<typename T>
void Parsable::registerParam(std::string name, T & variable,
ParamAccessType type,
const std::string description) {
std::map<std::string, ParsableParam *>::iterator it = params.find(name);
if(it != params.end()) AKANTU_EXCEPTION("Parameter named " << name << " already registered.");
ParsableParamTyped<T> * param = new ParsableParamTyped<T>(name, description, type,
variable);
params[name] = param;
}
/* -------------------------------------------------------------------------- */
template<typename T>
void Parsable::registerParam(std::string name, T & variable,
T default_value,
ParamAccessType type,
const std::string description) {
variable = default_value;
registerParam(name, variable, type, description);
}
/* -------------------------------------------------------------------------- */
template<typename T, typename V>
void Parsable::setMixed(const std::string & name, const V & value) {
std::map<std::string, ParsableParam *>::iterator it = params.find(name);
if(it == params.end()) AKANTU_EXCEPTION("No parameter named " << name << " in parsable.");
ParsableParam & param = *(it->second);
param.set<T>(value);
}
/* -------------------------------------------------------------------------- */
template<typename T>
void Parsable::set(const std::string & name, const T & value) {
this->template setMixed<T>(name, value);
}
/* -------------------------------------------------------------------------- */
template<typename T>
const T & Parsable::get(const std::string & name) const {
std::map<std::string, ParsableParam *>::const_iterator it = params.find(name);
if(it == params.end()) AKANTU_EXCEPTION("No parameter named " << name << " in parsable.");
const ParsableParam & param = *(it->second);
return param.get<T>();
}
/* -------------------------------------------------------------------------- */
template<typename T>
T & Parsable::get(const std::string & name) {
std::map<std::string, ParsableParam *>::iterator it = params.find(name);
if(it == params.end()) AKANTU_EXCEPTION("No parameter named " << name << " in parsable.");
ParsableParam & param = *(it->second);
return param.get<T>();
}
__END_AKANTU__
diff --git a/src/io/parser/parser.cc b/src/io/parser/parser.cc
index ec822b345..e166b1b53 100644
--- a/src/io/parser/parser.cc
+++ b/src/io/parser/parser.cc
@@ -1,98 +1,98 @@
/**
* @file parser.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Wed Jan 13 2016
*
* @brief implementation of the parser
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
// STL
#include <fstream>
#include <iomanip>
#include <map>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "parser.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
ParserSection::~ParserSection() { this->clean(); }
/* -------------------------------------------------------------------------- */
ParserParameter & ParserSection::addParameter(const ParserParameter & param) {
if (parameters.find(param.getName()) != parameters.end())
AKANTU_EXCEPTION("The parameter \"" + param.getName() +
"\" is already defined in this section");
return (parameters.insert(std::pair<std::string, ParserParameter>(
param.getName(), param)).first->second);
}
/* -------------------------------------------------------------------------- */
ParserSection & ParserSection::addSubSection(const ParserSection & section) {
return ((sub_sections_by_type.insert(std::pair<SectionType, ParserSection>(
section.getType(), section)))->second);
}
/* -------------------------------------------------------------------------- */
std::string Parser::getLastParsedFile() const { return last_parsed_file; }
/* -------------------------------------------------------------------------- */
void ParserSection::printself(std::ostream & stream,
unsigned int indent) const {
std::string space;
std::string ind = AKANTU_INDENT;
for (unsigned int i = 0; i < indent; i++, space += ind)
;
stream << space << "Section(" << this->type << ") " << this->name
<< (option != "" ? (" " + option) : "") << " [" << std::endl;
if (!this->parameters.empty()) {
stream << space << ind << "Parameters [" << std::endl;
Parameters::const_iterator pit = this->parameters.begin();
for (; pit != this->parameters.end(); ++pit) {
stream << space << ind << " + ";
pit->second.printself(stream);
stream << std::endl;
}
stream << space << ind << "]" << std::endl;
}
if (!this->sub_sections_by_type.empty()) {
stream << space << ind << "Subsections [" << std::endl;
SubSections::const_iterator sit = this->sub_sections_by_type.begin();
for (; sit != this->sub_sections_by_type.end(); ++sit)
sit->second.printself(stream, indent + 2);
stream << std::endl;
stream << space << ind << "]" << std::endl;
}
stream << space << "]" << std::endl;
}
__END_AKANTU__
diff --git a/src/io/parser/parser.hh b/src/io/parser/parser.hh
index 4e9d2d476..bab4298cb 100644
--- a/src/io/parser/parser.hh
+++ b/src/io/parser/parser.hh
@@ -1,467 +1,467 @@
/**
* @file parser.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Thu Aug 21 2014
+ * @date last modification: Wed Jan 13 2016
*
* @brief File parser interface
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_random_generator.hh"
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PARSER_HH__
#define __AKANTU_PARSER_HH__
__BEGIN_AKANTU__
#define AKANTU_SECTION_TYPES \
(global)(material)(model)(mesh)(heat)(contact)(friction)( \
embedded_interface)(rules)(neighborhoods)(non_local)(weight_function)( \
neighborhood)(user)(not_defined)
#define AKANTU_SECTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_st_, elem)
#define AKANTU_SECT_PREFIX(s, data, elem) AKANTU_SECTION_TYPES_PREFIX(elem)
/// Defines the possible section types
enum SectionType {
BOOST_PP_SEQ_ENUM(
BOOST_PP_SEQ_TRANSFORM(AKANTU_SECT_PREFIX, _, AKANTU_SECTION_TYPES))
};
#undef AKANTU_SECT_PREFIX
#define AKANTU_SECTION_TYPE_PRINT_CASE(r, data, elem) \
case AKANTU_SECTION_TYPES_PREFIX(elem): { \
stream << BOOST_PP_STRINGIZE(AKANTU_SECTION_TYPES_PREFIX(elem)); \
break; \
}
inline std::ostream & operator<<(std::ostream & stream, SectionType type) {
switch (type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_PRINT_CASE, _,
AKANTU_SECTION_TYPES)
default:
stream << "not a SectionType";
break;
}
return stream;
}
#undef AKANTU_SECTION_TYPE_PRINT_CASE
/// Defines the possible search contexts/scopes (for parameter search)
enum ParserParameterSearchCxt {
_ppsc_current_scope = 0x1,
_ppsc_parent_scope = 0x2,
_ppsc_current_and_parent_scope = 0x3
};
/* ------------------------------------------------------------------------ */
/* Parameters Class */
/* ------------------------------------------------------------------------ */
class ParserSection;
/// @brief The ParserParameter objects represent the end of tree branches as
/// they
/// are the different informations contained in the input file.
class ParserParameter {
public:
ParserParameter()
: parent_section(NULL), name(std::string()), value(std::string()),
dbg_filename(std::string()) {}
ParserParameter(const std::string & name, const std::string & value,
const ParserSection & parent_section)
: parent_section(&parent_section), name(name), value(value),
dbg_filename(std::string()) {}
ParserParameter(const ParserParameter & param)
: parent_section(param.parent_section), name(param.name),
value(param.value), dbg_filename(param.dbg_filename),
dbg_line(param.dbg_line), dbg_column(param.dbg_column) {}
virtual ~ParserParameter() {}
/// Get parameter name
const std::string & getName() const { return name; }
/// Get parameter value
const std::string & getValue() const { return value; }
/// Set info for debug output
void setDebugInfo(const std::string & filename, UInt line, UInt column) {
dbg_filename = filename;
dbg_line = line;
dbg_column = column;
}
template <typename T> inline operator T() const;
// template <typename T> inline operator Vector<T>() const;
// template <typename T> inline operator Matrix<T>() const;
/// Print parameter info in stream
void printself(std::ostream & stream, unsigned int indent = 0) const {
stream << name << ": " << value << " (" << dbg_filename << ":" << dbg_line
<< ":" << dbg_column << ")";
}
private:
void setParent(const ParserSection & sect) { parent_section = &sect; }
friend class ParserSection;
private:
/// Pointer to the parent section
const ParserSection * parent_section;
/// Name of the parameter
std::string name;
/// Value of the parameter
std::string value;
/// File for debug output
std::string dbg_filename;
/// Position of parameter in parsed file
UInt dbg_line, dbg_column;
};
/* ------------------------------------------------------------------------ */
/* Sections Class */
/* ------------------------------------------------------------------------ */
/// ParserSection represents a branch of the parsing tree.
class ParserSection {
public:
typedef std::multimap<SectionType, ParserSection> SubSections;
typedef std::map<std::string, ParserParameter> Parameters;
private:
typedef SubSections::const_iterator const_section_iterator_;
public:
/* ------------------------------------------------------------------------ */
/* SubSection iterator */
/* ------------------------------------------------------------------------ */
/// Iterator on sections
class const_section_iterator {
public:
const_section_iterator(const const_section_iterator & other)
: it(other.it) {}
const_section_iterator(const const_section_iterator_ & it) : it(it) {}
const_section_iterator & operator=(const const_section_iterator & other) {
if (this != &other) {
it = other.it;
}
return *this;
}
const ParserSection & operator*() const { return it->second; }
const ParserSection * operator->() const { return &(it->second); }
bool operator==(const const_section_iterator & other) const {
return it == other.it;
}
bool operator!=(const const_section_iterator & other) const {
return it != other.it;
}
const_section_iterator & operator++() {
++it;
return *this;
}
const_section_iterator operator++(int) {
const_section_iterator tmp = *this;
operator++();
return tmp;
}
private:
const_section_iterator_ it;
};
/* ------------------------------------------------------------------------ */
/* Parameters iterator */
/* ------------------------------------------------------------------------ */
/// Iterator on parameters
class const_parameter_iterator {
public:
const_parameter_iterator(const const_parameter_iterator & other)
: it(other.it) {}
const_parameter_iterator(const Parameters::const_iterator & it) : it(it) {}
const_parameter_iterator &
operator=(const const_parameter_iterator & other) {
if (this != &other) {
it = other.it;
}
return *this;
}
const ParserParameter & operator*() const { return it->second; }
const ParserParameter * operator->() { return &(it->second); };
bool operator==(const const_parameter_iterator & other) const {
return it == other.it;
}
bool operator!=(const const_parameter_iterator & other) const {
return it != other.it;
}
const_parameter_iterator & operator++() {
++it;
return *this;
}
const_parameter_iterator operator++(int) {
const_parameter_iterator tmp = *this;
operator++();
return tmp;
}
private:
Parameters::const_iterator it;
};
/* ---------------------------------------------------------------------- */
ParserSection()
: parent_section(NULL), name(std::string()), type(_st_not_defined) {}
ParserSection(const std::string & name, SectionType type)
: parent_section(NULL), name(name), type(type) {}
ParserSection(const std::string & name, SectionType type,
const std::string & option,
const ParserSection & parent_section)
: parent_section(&parent_section), name(name), type(type),
option(option) {}
ParserSection(const ParserSection & section)
: parent_section(section.parent_section), name(section.name),
type(section.type), option(section.option),
parameters(section.parameters),
sub_sections_by_type(section.sub_sections_by_type) {
setChldrenPointers();
}
ParserSection & operator=(const ParserSection & other) {
if (&other != this) {
parent_section = other.parent_section;
name = other.name;
type = other.type;
option = other.option;
parameters = other.parameters;
sub_sections_by_type = other.sub_sections_by_type;
setChldrenPointers();
}
return *this;
}
virtual ~ParserSection();
virtual void printself(std::ostream & stream, unsigned int indent = 0) const;
/* ---------------------------------------------------------------------- */
/* Creation functions */
/* ---------------------------------------------------------------------- */
public:
ParserParameter & addParameter(const ParserParameter & param);
ParserSection & addSubSection(const ParserSection & section);
protected:
/// Clean ParserSection content
void clean() {
parameters.clear();
sub_sections_by_type.clear();
}
private:
void setChldrenPointers() {
Parameters::iterator pit = this->parameters.begin();
for (; pit != this->parameters.end(); ++pit)
pit->second.setParent(*this);
SubSections::iterator sit = this->sub_sections_by_type.begin();
for (; sit != this->sub_sections_by_type.end(); ++sit)
sit->second.setParent(*this);
}
/* ---------------------------------------------------------------------- */
/* Accessors */
/* ---------------------------------------------------------------------- */
public:
/// Get begin and end iterators on subsections of certain type
std::pair<const_section_iterator, const_section_iterator>
getSubSections(SectionType type = _st_not_defined) const {
if (type != _st_not_defined) {
std::pair<const_section_iterator_, const_section_iterator_> range =
sub_sections_by_type.equal_range(type);
return std::pair<const_section_iterator, const_section_iterator>(
range.first, range.second);
} else {
return std::pair<const_section_iterator, const_section_iterator>(
sub_sections_by_type.begin(), sub_sections_by_type.end());
}
}
/// Get begin and end iterators on parameters
std::pair<const_parameter_iterator, const_parameter_iterator>
getParameters() const {
return std::pair<const_parameter_iterator, const_parameter_iterator>(
parameters.begin(), parameters.end());
}
/* ---------------------------------------------------------------------- */
/// Get parameter within specified context
const ParserParameter & getParameter(
const std::string & name,
ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
Parameters::const_iterator it;
if (search_ctx & _ppsc_current_scope)
it = parameters.find(name);
if (it == parameters.end()) {
if ((search_ctx & _ppsc_parent_scope) && parent_section)
return parent_section->getParameter(name, search_ctx);
else {
AKANTU_SILENT_EXCEPTION(
"The parameter " << name
<< " has not been found in the specified context");
}
}
return it->second;
}
/* ------------------------------------------------------------------------ */
/// Check if parameter exists within specified context
bool hasParameter(
const std::string & name,
ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
Parameters::const_iterator it;
if (search_ctx & _ppsc_current_scope)
it = parameters.find(name);
if (it == parameters.end()) {
if ((search_ctx & _ppsc_parent_scope) && parent_section)
return parent_section->hasParameter(name, search_ctx);
else {
return false;
}
}
return true;
}
/* --------------------------------------------------------------------------
*/
/// Get value of given parameter in context
template <class T>
T getParameterValue(
const std::string & name,
ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
const ParserParameter & tmp_param = getParameter(name, search_ctx);
T t = tmp_param;
return t;
}
/* --------------------------------------------------------------------------
*/
/// Get section name
const std::string & getName() const { return name; }
/// Get section type
const SectionType & getType() const { return type; }
/// Get section option
const std::string & getOption() const { return option; }
protected:
void setParent(const ParserSection & sect) { parent_section = &sect; }
/* ---------------------------------------------------------------------- */
/* Members */
/* ---------------------------------------------------------------------- */
private:
/// Pointer to the parent section
const ParserSection * parent_section;
/// Name of section
std::string name;
/// Type of section, see AKANTU_SECTION_TYPES
SectionType type;
/// Section option
std::string option;
/// Map of parameters in section
Parameters parameters;
/// Multi-map of subsections
SubSections sub_sections_by_type;
};
/* ------------------------------------------------------------------------ */
/* Parser Class */
/* ------------------------------------------------------------------------ */
/// Root of parsing tree, represents the global ParserSection
class Parser : public ParserSection {
public:
Parser() : ParserSection("global", _st_global) {}
void parse(const std::string & filename);
std::string getLastParsedFile() const;
static bool isPermissive() { return permissive_parser; }
public:
/// Parse real scalar
static Real parseReal(const std::string & value,
const ParserSection & section);
/// Parse real vector
static Vector<Real> parseVector(const std::string & value,
const ParserSection & section);
/// Parse real matrix
static Matrix<Real> parseMatrix(const std::string & value,
const ParserSection & section);
/// Parse real random parameter
static RandomParameter<Real>
parseRandomParameter(const std::string & value,
const ParserSection & section);
protected:
/// General parse function
template <class T, class Grammar>
static T parseType(const std::string & value, Grammar & grammar);
protected:
// friend class Parsable;
static bool permissive_parser;
std::string last_parsed_file;
};
inline std::ostream & operator<<(std::ostream & stream,
const ParserParameter & _this) {
_this.printself(stream);
return stream;
}
inline std::ostream & operator<<(std::ostream & stream,
const ParserSection & section) {
section.printself(stream);
return stream;
}
__END_AKANTU__
#include "parser_tmpl.hh"
#endif /* __AKANTU_PARSER_HH__ */
diff --git a/src/io/parser/parser_grammar_tmpl.hh b/src/io/parser/parser_grammar_tmpl.hh
index e91e0a691..fd2aefc0c 100644
--- a/src/io/parser/parser_grammar_tmpl.hh
+++ b/src/io/parser/parser_grammar_tmpl.hh
@@ -1,82 +1,81 @@
/**
- * @file parsable_tmpl.hh
+ * @file parser_grammar_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Jun 24 2014
+ * @date creation: Wed Nov 11 2015
*
* @brief implementation of the templated part of ParsableParam Parsable and
* ParsableParamTyped
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
//#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/spirit/include/classic_position_iterator.hpp>
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_PARSER_GRAMMAR_TMPL_HH
#define AKANTU_PARSER_GRAMMAR_TMPL_HH
__BEGIN_AKANTU__
namespace qi = boost::spirit::qi;
/* -------------------------------------------------------------------------- */
template <class T, class Grammar>
T Parser::parseType(const std::string & value, Grammar & grammar) {
using boost::spirit::ascii::space;
std::string::const_iterator b = value.begin();
std::string::const_iterator e = value.end();
T resultat = T();
bool res = false;
try {
res = qi::phrase_parse(b, e, grammar, space, resultat);
} catch(debug::Exception & ex) {
AKANTU_EXCEPTION("Could not parse '" << value << "' as a "
<< debug::demangle(typeid(T).name()) << ", an unknown error append '"
<< ex.what());
}
if(!res || (b != e)) {
AKANTU_EXCEPTION("Could not parse '" << value << "' as a "
<< debug::demangle(typeid(T).name()) << ", an unknown error append '"
<< std::string(value.begin(), b) << "<HERE>" << std::string(b, e) << "'");
}
return resultat;
}
namespace parser {
template<class Iterator>
struct Skipper {
typedef qi::rule<Iterator, void()> type;
};
}
__END_AKANTU__
#endif //AKANTU_PARSER_GRAMMAR_TMPL_HH
diff --git a/src/io/parser/parser_input_files.cc b/src/io/parser/parser_input_files.cc
index 1f3fc5679..aaf08d3cd 100644
--- a/src/io/parser/parser_input_files.cc
+++ b/src/io/parser/parser_input_files.cc
@@ -1,97 +1,97 @@
/**
- * @file parser.cc
+ * @file parser_input_files.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Wed Nov 11 2015
+ * @date last modification: Wed Jan 13 2016
*
* @brief implementation of the parser
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "parser_grammar_tmpl.hh"
/* -------------------------------------------------------------------------- */
#include "input_file_parser.hh"
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
__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<spirit::istream_iterator>
pos_iterator_type;
pos_iterator_type position_begin(fwd_begin, fwd_end, filename);
pos_iterator_type position_end;
// parse
parser::InputFileGrammar<pos_iterator_type> 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__
diff --git a/src/io/parser/parser_random.cc b/src/io/parser/parser_random.cc
index ccd7ab25b..7f281cdea 100644
--- a/src/io/parser/parser_random.cc
+++ b/src/io/parser/parser_random.cc
@@ -1,58 +1,58 @@
/**
- * @file parser.cc
+ * @file parser_random.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Mon Dec 07 2015
*
* @brief implementation of the parser
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "parser_grammar_tmpl.hh"
/* -------------------------------------------------------------------------- */
#include "algebraic_parser.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
RandomParameter<Real> Parser::parseRandomParameter(const std::string & value, const ParserSection & section) {
using boost::spirit::ascii::space_type;
parser::RandomGeneratorGrammar<std::string::const_iterator, space_type> grammar(section);
grammar.name("random_grammar");
parser::ParsableRandomGenerator rg = Parser::parseType<parser::ParsableRandomGenerator>(value, grammar);
Vector<Real> params = rg.parameters;
switch(rg.type) {
case _rdt_not_defined: return RandomParameter<Real>(rg.base);
case _rdt_uniform: return RandomParameter<Real>(rg.base, UniformDistribution<Real>(params(0), params(1)));
case _rdt_weibull: return RandomParameter<Real>(rg.base, WeibullDistribution<Real>(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 b5a5ecb85..666d8f0ce 100644
--- a/src/io/parser/parser_real.cc
+++ b/src/io/parser/parser_real.cc
@@ -1,48 +1,48 @@
/**
- * @file parser.cc
+ * @file parser_real.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Wed Nov 11 2015
*
* @brief implementation of the parser
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#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<std::string::const_iterator, space_type> grammar(section);
grammar.name("algebraic_grammar");
return Parser::parseType<Real>(value, grammar);
}
__END_AKANTU__
\ No newline at end of file
diff --git a/src/io/parser/parser_tmpl.hh b/src/io/parser/parser_tmpl.hh
index 5b722dd73..336ffef75 100644
--- a/src/io/parser/parser_tmpl.hh
+++ b/src/io/parser/parser_tmpl.hh
@@ -1,106 +1,106 @@
/**
* @file parser_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Tue Jun 24 2014
+ * @date last modification: Wed Apr 22 2015
*
* @brief Implementation of the parser templated methods
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <typename T>
inline ParserParameter::operator T() const {
T t;
std::stringstream sstr(value);
sstr >> t;
if(sstr.bad())
AKANTU_EXCEPTION("No known conversion of a ParserParameter \""
<< name << "\" to the type "
<< typeid(T).name());
return t;
}
/* -------------------------------------------------------------------------- */
template<>
inline ParserParameter::operator const char *() const {
return value.c_str();
}
/* -------------------------------------------------------------------------- */
template<>
inline ParserParameter::operator Real() const {
return Parser::parseReal(value, *parent_section);
}
/* --------------------------------------------------------- ----------------- */
template<>
inline ParserParameter::operator bool() const {
bool b;
std::stringstream sstr(value);
sstr >> std::boolalpha >> b;
if(sstr.fail()) {
sstr.clear();
sstr >> std::noboolalpha >> b;
}
return b;
}
/* --------------------------------------------------------- ----------------- */
template<>
inline ParserParameter::operator Vector<Real>() const {
return Parser::parseVector(value, *parent_section);
}
/* --------------------------------------------------------- ----------------- */
template<>
inline ParserParameter::operator Vector<UInt>() const {
Vector<Real> tmp = Parser::parseVector(value, *parent_section);
Vector<UInt> tmp_uint(tmp.size());
for (UInt i=0; i<tmp.size(); ++i) {
tmp_uint(i) = UInt(tmp(i));
}
return tmp_uint;
}
/* --------------------------------------------------------- ----------------- */
template<>
inline ParserParameter::operator Matrix<Real>() const {
return Parser::parseMatrix(value, *parent_section);
}
/* -------------------------------------------------------------------------- */
template<>
inline ParserParameter::operator RandomParameter<Real>() const {
return Parser::parseRandomParameter(value, *parent_section);
}
__END_AKANTU__
diff --git a/src/io/parser/parser_types.cc b/src/io/parser/parser_types.cc
index 63d2d19ca..f829f7279 100644
--- a/src/io/parser/parser_types.cc
+++ b/src/io/parser/parser_types.cc
@@ -1,58 +1,58 @@
/**
- * @file parser.cc
+ * @file parser_types.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Wed Nov 11 2015
*
* @brief implementation of the parser
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "parser_grammar_tmpl.hh"
/* -------------------------------------------------------------------------- */
#include "algebraic_parser.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
Vector<Real> Parser::parseVector(const std::string & value, const ParserSection & section) {
using boost::spirit::ascii::space_type;
parser::VectorGrammar<std::string::const_iterator, space_type> grammar(section);
grammar.name("vector_grammar");
return Parser::parseType<parser::parsable_vector>(value, grammar);
}
/* -------------------------------------------------------------------------- */
Matrix<Real> Parser::parseMatrix(const std::string & value, const ParserSection & section) {
using boost::spirit::ascii::space_type;
parser::MatrixGrammar<std::string::const_iterator, space_type> grammar(section);
grammar.name("matrix_grammar");
return Parser::parseType<parser::parsable_matrix>(value, grammar);
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
\ No newline at end of file
diff --git a/src/mesh/element_group.cc b/src/mesh/element_group.cc
index e6241ec00..24bf91037 100644
--- a/src/mesh/element_group.cc
+++ b/src/mesh/element_group.cc
@@ -1,200 +1,201 @@
/**
* @file element_group.cc
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Tue Aug 18 2015
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <sstream>
#include <algorithm>
#include <iterator>
#include "mesh.hh"
#include "group_manager.hh"
#include "group_manager_inline_impl.cc"
#include "dumpable.hh"
#include "dumpable_inline_impl.hh"
#include "aka_csr.hh"
#include "mesh_utils.hh"
#include "element_group.hh"
#if defined(AKANTU_USE_IOHELPER)
# include "dumper_paraview.hh"
#endif
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
ElementGroup::ElementGroup(const std::string & group_name,
const Mesh & mesh,
NodeGroup & node_group,
UInt dimension,
const std::string & id,
const MemoryID & mem_id) :
Memory(id, mem_id),
mesh(mesh),
name(group_name),
elements("elements", id, mem_id),
node_group(node_group),
dimension(dimension) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_USE_IOHELPER)
this->registerDumper<DumperParaview>("paraview_" + group_name, group_name, true);
this->addDumpFilteredMesh(mesh, elements, node_group.getNodes(), dimension);
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::empty() {
elements.free();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::append(const ElementGroup & other_group) {
AKANTU_DEBUG_IN();
node_group.append(other_group.node_group);
/// loop on all element types in all dimensions
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
type_iterator it = other_group.firstType(_all_dimensions,
ghost_type,
_ek_not_defined);
type_iterator last = other_group.lastType(_all_dimensions,
ghost_type,
_ek_not_defined);
for (; it != last; ++it) {
ElementType type = *it;
const Array<UInt> & other_elem_list = other_group.elements(type, ghost_type);
UInt nb_other_elem = other_elem_list.getSize();
Array<UInt> * elem_list;
UInt nb_elem = 0;
/// create current type if doesn't exists, otherwise get information
if (elements.exists(type, ghost_type)) {
elem_list = &elements(type, ghost_type);
nb_elem = elem_list->getSize();
}
else {
elem_list = &(elements.alloc(0, 1, type, ghost_type));
}
/// append new elements to current list
elem_list->resize(nb_elem + nb_other_elem);
std::copy(other_elem_list.begin(),
other_elem_list.end(),
elem_list->begin() + nb_elem);
/// remove duplicates
std::sort(elem_list->begin(), elem_list->end());
Array<UInt>::iterator<> end = std::unique(elem_list->begin(), elem_list->end());
elem_list->resize(end - elem_list->begin());
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "ElementGroup [" << std::endl;
stream << space << " + name: " << name << std::endl;
stream << space << " + dimension: " << dimension << std::endl;
elements.printself(stream, indent + 1);
node_group.printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
void ElementGroup::optimize() {
// increasing the locality of data when iterating on the element of a group
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
ElementList::type_iterator it = elements.firstType(_all_dimensions, ghost_type);
ElementList::type_iterator last = elements.lastType(_all_dimensions, ghost_type);
for (; it != last; ++it) {
Array<UInt> & els = elements(*it, ghost_type);
std::sort(els.begin(), els.end());
Array<UInt>::iterator<> end = std::unique(els.begin(), els.end());
els.resize(end - els.begin());
}
}
node_group.optimize();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::fillFromNodeGroup() {
CSR<Element> node_to_elem;
MeshUtils::buildNode2Elements(this->mesh, node_to_elem, this->dimension);
std::set<Element> seen;
Array<UInt>::const_iterator<> itn = this->node_group.begin();
Array<UInt>::const_iterator<> endn = this->node_group.end();
for (;itn != endn; ++itn) {
CSR<Element>::iterator ite = node_to_elem.begin(*itn);
CSR<Element>::iterator ende = node_to_elem.end(*itn);
for (;ite != ende; ++ite) {
const Element & elem = *ite;
if(this->dimension != _all_dimensions && this->dimension != Mesh::getSpatialDimension(elem.type)) continue;
if(seen.find(elem) != seen.end()) continue;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(elem.type);
Array<UInt>::const_iterator< Vector<UInt> > conn_it =
this->mesh.getConnectivity(elem.type, elem.ghost_type).begin(nb_nodes_per_element);
const Vector<UInt> & conn = conn_it[elem.element];
UInt count = 0;
for (UInt n = 0; n < conn.size(); ++n) {
count += (this->node_group.getNodes().find(conn(n)) != -1 ? 1 : 0);
}
if(count == nb_nodes_per_element) this->add(elem);
seen.insert(elem);
}
}
this->optimize();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/mesh/element_group.hh b/src/mesh/element_group.hh
index 38ec48f84..7dcc766e1 100644
--- a/src/mesh/element_group.hh
+++ b/src/mesh/element_group.hh
@@ -1,179 +1,179 @@
/**
* @file element_group.hh
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 03 2013
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_GROUP_HH__
#define __AKANTU_ELEMENT_GROUP_HH__
#include <set>
#include "aka_common.hh"
#include "aka_memory.hh"
#include "element_type_map.hh"
#include "node_group.hh"
#include "dumpable.hh"
__BEGIN_AKANTU__
class Mesh;
class Element;
/* -------------------------------------------------------------------------- */
class ElementGroup : private Memory, public Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ElementGroup(const std::string & name,
const Mesh & mesh,
NodeGroup & node_group,
UInt dimension = _all_dimensions,
const std::string & id = "element_group",
const MemoryID & memory_id = 0);
/* ------------------------------------------------------------------------ */
/* Type definitions */
/* ------------------------------------------------------------------------ */
public:
typedef ElementTypeMapArray<UInt> ElementList;
typedef Array<UInt> NodeList;
/* ------------------------------------------------------------------------ */
/* Node iterator */
/* ------------------------------------------------------------------------ */
typedef NodeGroup::const_node_iterator const_node_iterator;
inline const_node_iterator node_begin() const;
inline const_node_iterator node_end() const;
/* ------------------------------------------------------------------------ */
/* Element iterator */
/* ------------------------------------------------------------------------ */
typedef ElementList::type_iterator type_iterator;
inline type_iterator firstType(UInt dim = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & kind = _ek_regular) const;
inline type_iterator lastType(UInt dim = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & kind = _ek_regular) const;
typedef Array<UInt>::const_iterator<UInt> const_element_iterator;
inline const_element_iterator element_begin(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
inline const_element_iterator element_end(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// empty the element group
void empty();
/// append another group to this group
/// BE CAREFUL: it doesn't conserve the element order
void append(const ElementGroup & other_group);
/// add an element to the group. By default the it does not add the nodes to the group
inline void add(const Element & el, bool add_nodes = false, bool check_for_duplicate = true);
/// \todo fix the default for add_nodes : make it coherent with the other method
inline void add(const ElementType & type, UInt element,
const GhostType & ghost_type = _not_ghost,
bool add_nodes = true, bool check_for_duplicate = true);
inline void addNode(UInt node_id, bool check_for_duplicate = true);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/// fill the elements based on the underlying node group.
virtual void fillFromNodeGroup();
// sort and remove duplicated values
void optimize();
private:
inline void addElement(const ElementType & elem_type,
UInt elem_id,
const GhostType & ghost_type);
friend class GroupManager;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Elements, elements, UInt);
AKANTU_GET_MACRO(Elements, elements, const ElementTypeMapArray<UInt> &);
AKANTU_GET_MACRO(Nodes, node_group.getNodes(), const Array<UInt> &);
AKANTU_GET_MACRO(NodeGroup, node_group, const NodeGroup &);
AKANTU_GET_MACRO_NOT_CONST(NodeGroup, node_group, NodeGroup &);
AKANTU_GET_MACRO(Dimension, dimension, UInt);
AKANTU_GET_MACRO(Name, name, std::string);
inline UInt getNbNodes() const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// Mesh to which this group belongs
const Mesh & mesh;
/// name of the group
std::string name;
/// list of elements composing the group
ElementList elements;
/// sub list of nodes which are composing the elements
NodeGroup & node_group;
/// group dimension
UInt dimension;
/// empty arry for the iterator to work when an element type not present
Array<UInt> empty_elements;
};
/// standard output stream operator
inline std::ostream & operator << (std::ostream & stream, const ElementGroup &_this) {
_this.printself(stream);
return stream;
}
__END_AKANTU__
#include "element.hh"
#include "element_group_inline_impl.cc"
#endif /* __AKANTU_ELEMENT_GROUP_HH__ */
diff --git a/src/mesh/element_group_inline_impl.cc b/src/mesh/element_group_inline_impl.cc
index e9effa1b3..e7475c19e 100644
--- a/src/mesh/element_group_inline_impl.cc
+++ b/src/mesh/element_group_inline_impl.cc
@@ -1,127 +1,127 @@
/**
* @file element_group_inline_impl.cc
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Tue Aug 18 2015
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline void ElementGroup::add(const Element & el, bool add_nodes,
bool check_for_duplicate) {
this->add(el.type,el.element,el.ghost_type,add_nodes,check_for_duplicate);
}
/* -------------------------------------------------------------------------- */
inline void ElementGroup::add(const ElementType & type, UInt element,
const GhostType & ghost_type,bool add_nodes,
bool check_for_duplicate) {
addElement(type, element, ghost_type);
if(add_nodes) {
Array<UInt>::const_vector_iterator it =
mesh.getConnectivity(type, ghost_type).begin(mesh.getNbNodesPerElement(type)) + element;
const Vector<UInt> & conn = *it;
for (UInt i = 0; i < conn.size(); ++i) addNode(conn[i], check_for_duplicate);
}
}
/* -------------------------------------------------------------------------- */
inline void ElementGroup::addNode(UInt node_id, bool check_for_duplicate) {
node_group.add(node_id, check_for_duplicate);
}
/* -------------------------------------------------------------------------- */
inline void ElementGroup::addElement(const ElementType & elem_type,
UInt elem_id,
const GhostType & ghost_type) {
if(!(elements.exists(elem_type, ghost_type))) {
elements.alloc(0, 1, elem_type, ghost_type);
}
elements(elem_type, ghost_type).push_back(elem_id);
this->dimension = UInt(std::max(Int(this->dimension), Int(mesh.getSpatialDimension(elem_type))));
}
/* -------------------------------------------------------------------------- */
inline UInt ElementGroup::getNbNodes() const {
return node_group.getSize();
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::const_node_iterator ElementGroup::node_begin() const {
return node_group.begin();
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::const_node_iterator ElementGroup::node_end() const {
return node_group.end();
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::type_iterator ElementGroup::firstType(UInt dim,
const GhostType & ghost_type,
const ElementKind & kind) const {
return elements.firstType(dim, ghost_type, kind);
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::type_iterator ElementGroup::lastType(UInt dim,
const GhostType & ghost_type,
const ElementKind & kind) const {
return elements.lastType(dim, ghost_type, kind);
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::const_element_iterator ElementGroup::element_begin(const ElementType & type,
const GhostType & ghost_type) const {
if(elements.exists(type, ghost_type)) {
return elements(type, ghost_type).begin();
} else {
return empty_elements.begin();
}
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::const_element_iterator ElementGroup::element_end(const ElementType & type,
const GhostType & ghost_type) const {
if(elements.exists(type, ghost_type)) {
return elements(type, ghost_type).end();
} else {
return empty_elements.end();
}
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/mesh/element_type_map.hh b/src/mesh/element_type_map.hh
index 5c9121e6d..bcac63471 100644
--- a/src/mesh/element_type_map.hh
+++ b/src/mesh/element_type_map.hh
@@ -1,330 +1,331 @@
/**
* @file element_type_map.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 31 2011
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Fri Oct 02 2015
*
* @brief storage class by element type
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_TYPE_MAP_HH__
#define __AKANTU_ELEMENT_TYPE_MAP_HH__
#include "aka_common.hh"
#include "aka_array.hh"
#include "aka_memory.hh"
__BEGIN_AKANTU__
template<class Stored, typename SupportType = ElementType>
class ElementTypeMap;
/* -------------------------------------------------------------------------- */
/* ElementTypeMapBase */
/* -------------------------------------------------------------------------- */
/// Common non templated base class for the ElementTypeMap class
class ElementTypeMapBase {
public:
virtual ~ElementTypeMapBase() {};
};
/* -------------------------------------------------------------------------- */
/* ElementTypeMap */
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
class ElementTypeMap : public ElementTypeMapBase {
public:
ElementTypeMap();
~ElementTypeMap();
inline static std::string printType(const SupportType & type, const GhostType & ghost_type);
/*! Tests whether a type is present in the object
* @param type the type to check for
* @param ghost_type optional: by default, the data map for non-ghost
* elements is searched
* @return true if the type is present. */
inline bool exists(const SupportType & type, const GhostType & ghost_type = _not_ghost) const;
/*! get the stored data corresponding to a type
* @param type the type to check for
* @param ghost_type optional: by default, the data map for non-ghost
* elements is searched
* @return stored data corresponding to type. */
inline const Stored & operator()(const SupportType & type,
const GhostType & ghost_type = _not_ghost) const;
/*! get the stored data corresponding to a type
* @param type the type to check for
* @param ghost_type optional: by default, the data map for non-ghost
* elements is searched
* @return stored data corresponding to type. */
inline Stored & operator()(const SupportType & type,
const GhostType & ghost_type = _not_ghost);
/*! insert data of a new type (not yet present) into the map. THIS METHOD IS
* NOT ARRAY SAFE, when using ElementTypeMapArray, use setArray instead
* @param data to insert
* @param type type of data (if this type is already present in the map,
* an exception is thrown).
* @param ghost_type optional: by default, the data map for non-ghost
* elements is searched
* @return stored data corresponding to type. */
inline Stored & operator()(const Stored & insert,
const SupportType & type,
const GhostType & ghost_type = _not_ghost);
/// print helper
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Element type Iterator */
/* ------------------------------------------------------------------------ */
/*! iterator allows to iterate over type-data pairs of the map. The interface
* expects the SupportType to be ElementType. */
typedef std::map<SupportType, Stored> DataMap;
class type_iterator : private std::iterator<std::forward_iterator_tag, const SupportType> {
public:
typedef const SupportType value_type;
typedef const SupportType* pointer;
typedef const SupportType& reference;
protected:
typedef typename ElementTypeMap<Stored>::DataMap::const_iterator DataMapIterator;
public:
type_iterator(DataMapIterator & list_begin,
DataMapIterator & list_end,
UInt dim,
ElementKind ek);
type_iterator(const type_iterator & it);
type_iterator() {}
inline reference operator*();
inline reference operator*() const;
inline type_iterator & operator++();
type_iterator operator++(int);
inline bool operator==(const type_iterator & other) const;
inline bool operator!=(const type_iterator & other) const;
type_iterator & operator=(const type_iterator & other);
private:
DataMapIterator list_begin;
DataMapIterator list_end;
UInt dim;
ElementKind kind;
};
/*! Get an iterator to the beginning of a subset datamap. This method expects
* the SupportType to be ElementType.
* @param dim optional: iterate over data of dimension dim (e.g. when
* iterating over (surface) facets of a 3D mesh, dim would be 2).
* by default, all dimensions are considered.
* @param ghost_type optional: by default, the data map for non-ghost
* elements is iterated over.
* @param kind optional: the kind of element to search for (see
* aka_common.hh), by default all kinds are considered
* @return an iterator to the first stored data matching the filters
* or an iterator to the end of the map if none match*/
inline type_iterator firstType(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) const;
/*! Get an iterator to the end of a subset datamap. This method expects
* the SupportType to be ElementType.
* @param dim optional: iterate over data of dimension dim (e.g. when
* iterating over (surface) facets of a 3D mesh, dim would be 2).
* by default, all dimensions are considered.
* @param ghost_type optional: by default, the data map for non-ghost
* elements is iterated over.
* @param kind optional: the kind of element to search for (see
* aka_common.hh), by default all kinds are considered
* @return an iterator to the last stored data matching the filters
* or an iterator to the end of the map if none match */
inline type_iterator lastType(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) const;
protected:
/*! Direct access to the underlying data map. for internal use by daughter
* classes only
* @param ghost_type whether to return the data map or the ghost_data map
* @return the raw map */
inline DataMap & getData(GhostType ghost_type);
/*! Direct access to the underlying data map. for internal use by daughter
* classes only
* @param ghost_type whether to return the data map or the ghost_data map
* @return the raw map */
inline const DataMap & getData(GhostType ghost_type) const;
/* ------------------------------------------------------------------------ */
protected:
DataMap data;
DataMap ghost_data;
};
/* -------------------------------------------------------------------------- */
/* Some typedefs */
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType = ElementType>
class ElementTypeMapArray : public ElementTypeMap<Array<T> *, SupportType>, public Memory {
public:
typedef T type;
typedef Array<T> array_type;
protected:
typedef ElementTypeMap<Array<T> *, SupportType> parent;
typedef typename parent::DataMap DataMap;
private:
private:
/// standard assigment (copy) operator
void operator=(const ElementTypeMap<T, SupportType> &) {};
public:
typedef typename parent::type_iterator type_iterator;
/*! Constructor
* @param id optional: identifier (string)
* @param parent_id optional: parent identifier. for organizational purposes
* only
* @param memory_id optional: choose a specific memory, defaults to memory 0
*/
ElementTypeMapArray(const ID & id = "by_element_type_array", const ID & parent_id = "no_parent",
const MemoryID & memory_id = 0) :
parent(), Memory(parent_id + ":" + id, memory_id), name(id) {};
/*! allocate memory for a new array
* @param size number of tuples of the new array
* @param nb_component tuple size
* @param type the type under which the array is indexed in the map
* @param ghost_type whether to add the field to the data map or the
* ghost_data map
* @return a reference to the allocated array */
inline Array<T> & alloc(UInt size,
UInt nb_component,
const SupportType & type,
const GhostType & ghost_type,
const T & default_value = T());
/*! allocate memory for a new array in both the data and the ghost_data map
* @param size number of tuples of the new array
* @param nb_component tuple size
* @param type the type under which the array is indexed in the map*/
inline void alloc(UInt size,
UInt nb_component,
const SupportType & type,
const T & default_value = T());
/* get a reference to the array of certain type
* @param type data filed under type is returned
* @param ghost_type optional: by default the non-ghost map is searched
* @return a reference to the array */
inline const Array<T> & operator()(const SupportType & type,
const GhostType & ghost_type = _not_ghost) const;
/* get a reference to the array of certain type
* @param type data filed under type is returned
* @param ghost_type optional: by default the non-ghost map is searched
* @return a const reference to the array */
inline Array<T> & operator()(const SupportType & type,
const GhostType & ghost_type = _not_ghost);
/*! insert data of a new type (not yet present) into the map.
* @param type type of data (if this type is already present in the map,
* an exception is thrown).
* @param ghost_type optional: by default, the data map for non-ghost
* elements is searched
* @param vect the vector to include into the map
* @return stored data corresponding to type. */
inline void setArray(const SupportType & type,
const GhostType & ghost_type,
const Array<T> & vect);
/*! frees all memory related to the data*/
inline void free();
/*! set all values in the ElementTypeMap to zero*/
inline void clear();
/*! deletes and reorders entries in the stored arrays
* @param new_numbering a ElementTypeMapArray of new indices. UInt(-1) indicates
* deleted entries. */
inline void onElementsRemoved(const ElementTypeMapArray<UInt> & new_numbering);
/// text output helper
virtual void printself(std::ostream & stream, int indent = 0) const;
/*! set the id
* @param id the new name
*/
inline void setID(const ID & id) { this->id = id; }
ElementTypeMap<UInt> getNbComponents(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) const{
ElementTypeMap<UInt> nb_components;
type_iterator tit = this->firstType(dim,ghost_type,kind);
type_iterator end = this->lastType(dim,ghost_type,kind);
while (tit != end){
UInt nb_comp = (*this)(*tit,ghost_type).getNbComponent();
nb_components(*tit,ghost_type) = nb_comp;
++tit;
}
return nb_components;
}
/* -------------------------------------------------------------------------- */
/* Accesssors */
/* -------------------------------------------------------------------------- */
public:
/// get the name of the internal field
AKANTU_GET_MACRO(Name, name, ID);
private:
ElementTypeMapArray operator=(__attribute__((unused)) const ElementTypeMapArray & other) {};
/// name of the elment type map: e.g. connectivity, grad_u
ID name;
};
/// to store data Array<Real> by element type
typedef ElementTypeMapArray<Real> ElementTypeMapReal;
/// to store data Array<Int> by element type
typedef ElementTypeMapArray<Int> ElementTypeMapInt;
/// to store data Array<UInt> by element type
typedef ElementTypeMapArray<UInt, ElementType> ElementTypeMapUInt;
/// Map of data of type UInt stored in a mesh
typedef std::map<std::string, Array<UInt> *> UIntDataMap;
typedef ElementTypeMap<UIntDataMap, ElementType> ElementTypeMapUIntDataMap;
__END_AKANTU__
#endif /* __AKANTU_ELEMENT_TYPE_MAP_HH__ */
diff --git a/src/mesh/element_type_map_filter.hh b/src/mesh/element_type_map_filter.hh
index f419005ad..ff23be8d2 100644
--- a/src/mesh/element_type_map_filter.hh
+++ b/src/mesh/element_type_map_filter.hh
@@ -1,334 +1,335 @@
/**
* @file element_type_map_filter.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Fri Dec 18 2015
*
* @brief Filtered version based on a an akantu::ElementGroup of a
- *akantu::ElementTypeMap
+ * akantu::ElementTypeMap
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_BY_ELEMENT_TYPE_FILTER_HH__
#define __AKANTU_BY_ELEMENT_TYPE_FILTER_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* ArrayFilter */
/* -------------------------------------------------------------------------- */
template <typename T> class ArrayFilter {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
/// standard iterator
template <typename R = T> class iterator {
inline bool operator!=(iterator<R> & other) { throw; };
inline bool operator==(iterator<R> & other) { throw; };
inline iterator<R> & operator++() { throw; };
inline T operator*() {
throw;
return T();
};
};
/// const iterator
template <template <class S> class original_iterator, typename Shape,
typename filter_iterator>
class const_iterator {
public:
UInt getCurrentIndex() {
return (*this->filter_it * this->nb_item_per_elem +
this->sub_element_counter);
}
inline const_iterator(){};
inline const_iterator(const original_iterator<Shape> & origin_it,
const filter_iterator & filter_it,
UInt nb_item_per_elem)
: origin_it(origin_it), filter_it(filter_it),
nb_item_per_elem(nb_item_per_elem), sub_element_counter(0){};
inline bool operator!=(const_iterator & other) const {
return !((*this) == other);
}
inline bool operator==(const_iterator & other) const {
return (this->origin_it == other.origin_it &&
this->filter_it == other.filter_it &&
this->sub_element_counter == other.sub_element_counter);
}
inline bool operator!=(const const_iterator & other) const {
return !((*this) == other);
}
inline bool operator==(const const_iterator & other) const {
return (this->origin_it == other.origin_it &&
this->filter_it == other.filter_it &&
this->sub_element_counter == other.sub_element_counter);
}
inline const_iterator & operator++() {
++sub_element_counter;
if (sub_element_counter == nb_item_per_elem) {
sub_element_counter = 0;
++filter_it;
}
return *this;
};
inline Shape operator*() {
return origin_it[nb_item_per_elem * (*filter_it) + sub_element_counter];
};
private:
original_iterator<Shape> origin_it;
filter_iterator filter_it;
/// the number of item per element
UInt nb_item_per_elem;
/// counter for every sub element group
UInt sub_element_counter;
};
typedef iterator< Vector<T> > vector_iterator;
typedef Array<T> array_type;
typedef const_iterator< array_type::template const_iterator, Vector<T>,
Array<UInt>::const_iterator<UInt> >
const_vector_iterator;
typedef typename array_type::value_type value_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ArrayFilter(const Array<T> & array, const Array<UInt> & filter,
UInt nb_item_per_elem)
: array(array), filter(filter), nb_item_per_elem(nb_item_per_elem){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
const_vector_iterator begin_reinterpret(UInt n, UInt new_size) const {
AKANTU_DEBUG_ASSERT(
n * new_size == this->getNbComponent() * this->getSize(),
"The new values for size ("
<< new_size << ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->getSize() << "," << this->getNbComponent() << ")");
UInt new_full_array_size =
this->array.getSize() * array.getNbComponent() / n;
UInt new_nb_item_per_elem = this->nb_item_per_elem;
if (new_size != 0 && n != 0)
new_nb_item_per_elem = this->array.getNbComponent() *
this->filter.getSize() * this->nb_item_per_elem /
(n * new_size);
return const_vector_iterator(
this->array.begin_reinterpret(n, new_full_array_size),
this->filter.begin(), new_nb_item_per_elem);
};
const_vector_iterator end_reinterpret(UInt n, UInt new_size) const {
AKANTU_DEBUG_ASSERT(
n * new_size == this->getNbComponent() * this->getSize(),
"The new values for size ("
<< new_size << ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->getSize() << "," << this->getNbComponent() << ")");
UInt new_full_array_size =
this->array.getSize() * this->array.getNbComponent() / n;
UInt new_nb_item_per_elem = this->nb_item_per_elem;
if (new_size != 0 && n != 0)
new_nb_item_per_elem = this->array.getNbComponent() *
this->filter.getSize() * this->nb_item_per_elem /
(n * new_size);
return const_vector_iterator(
this->array.begin_reinterpret(n, new_full_array_size),
this->filter.end(), new_nb_item_per_elem);
};
vector_iterator begin_reinterpret(UInt, UInt) { throw; };
vector_iterator end_reinterpret(UInt, UInt) { throw; };
/// return the size of the filtered array which is the filter size
UInt getSize() const {
return this->filter.getSize() * this->nb_item_per_elem;
};
/// the number of components of the filtered array
UInt getNbComponent() const { return this->array.getNbComponent(); };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// reference to array of data
const Array<T> & array;
/// reference to the filter used to select elements
const Array<UInt> & filter;
/// the number of item per element
UInt nb_item_per_elem;
};
/* -------------------------------------------------------------------------- */
/* ElementTypeMapFilter */
/* -------------------------------------------------------------------------- */
template <class T, typename SupportType = ElementType>
class ElementTypeMapArrayFilter {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef T type;
typedef ArrayFilter<T> array_type;
typedef typename array_type::value_type value_type;
typedef typename ElementTypeMapArray<UInt, SupportType>::type_iterator
type_iterator;
// class type_iterator{
// public:
// typedef typename ElementTypeMapArray<T,SupportType>::type_iterator
// type_it;
// public:
// type_iterator(){};
// // type_iterator(const type_iterator & it){original_it =
// it.original_it;};
// type_iterator(const type_it & it){original_it = it;};
// inline ElementType & operator*(){throw;};
// inline ElementType & operator*() const{throw;};
// inline type_iterator & operator++(){throw;return *this;};
// type_iterator operator++(int){throw; return *this;};
// inline bool operator==(const type_iterator & other) const{throw;return
// false;};
// inline bool operator!=(const type_iterator & other) const{throw;return
// false;};
// // type_iterator & operator=(const type_iterator & other){throw;return
// *this;};
// type_it original_it;
// };
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ElementTypeMapArrayFilter(
const ElementTypeMapArray<T, SupportType> & array,
const ElementTypeMapArray<UInt, SupportType> & filter,
const ElementTypeMap<UInt, SupportType> & nb_data_per_elem)
: array(array), filter(filter), nb_data_per_elem(nb_data_per_elem) {}
ElementTypeMapArrayFilter(
const ElementTypeMapArray<T, SupportType> & array,
const ElementTypeMapArray<UInt, SupportType> & filter)
: array(array), filter(filter) {}
~ElementTypeMapArrayFilter() {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
inline const ArrayFilter<T>
operator()(const SupportType & type,
const GhostType & ghost_type = _not_ghost) const {
if (filter.exists(type, ghost_type)) {
if (nb_data_per_elem.exists(type, ghost_type))
return ArrayFilter<T>(array(type, ghost_type), filter(type, ghost_type),
nb_data_per_elem(type, ghost_type) /
array(type, ghost_type).getNbComponent());
else
return ArrayFilter<T>(array(type, ghost_type), filter(type, ghost_type),
1);
} else {
return ArrayFilter<T>(empty_array, empty_filter, 1);
}
};
inline type_iterator firstType(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) const {
return filter.firstType(dim, _not_ghost, kind);
};
inline type_iterator lastType(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) const {
return filter.lastType(dim, _not_ghost, kind);
};
ElementTypeMap<UInt>
getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) const {
return this->array.getNbComponents(dim, ghost_type, kind);
};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
std::string getID() {
return std::string("filtered:" + this->array().getID());
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
const ElementTypeMapArray<T, SupportType> & array;
const ElementTypeMapArray<UInt, SupportType> & filter;
ElementTypeMap<UInt> nb_data_per_elem;
/// Empty array to be able to return consistent filtered arrays
Array<T> empty_array;
Array<UInt> empty_filter;
};
__END_AKANTU__
#endif /* __AKANTU_BY_ELEMENT_TYPE_FILTER_HH__ */
diff --git a/src/mesh/element_type_map_tmpl.hh b/src/mesh/element_type_map_tmpl.hh
index f382b45de..18e9a09a5 100644
--- a/src/mesh/element_type_map_tmpl.hh
+++ b/src/mesh/element_type_map_tmpl.hh
@@ -1,457 +1,458 @@
/**
* @file element_type_map_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 31 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Fri Oct 02 2015
*
* @brief implementation of template functions of the ElementTypeMap and
* ElementTypeMapArray classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__
#define __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* ElementTypeMap */
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline std::string ElementTypeMap<Stored, SupportType>::printType(const SupportType & type,
const GhostType & ghost_type) {
std::stringstream sstr; sstr << "(" << ghost_type << ":" << type << ")";
return sstr.str();
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline bool ElementTypeMap<Stored, SupportType>::exists(const SupportType & type, const GhostType & ghost_type) const {
return this->getData(ghost_type).find(type) != this->getData(ghost_type).end();
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline const Stored & ElementTypeMap<Stored, SupportType>::operator()(const SupportType & type,
const GhostType & ghost_type) const {
typename DataMap::const_iterator it =
this->getData(ghost_type).find(type);
if(it == this->getData(ghost_type).end())
AKANTU_EXCEPTION("No element of type "
<< ElementTypeMap::printType(type, ghost_type)
<< " in this ElementTypeMap<"
<< debug::demangle(typeid(Stored).name()) << "> class");
return it->second;
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline Stored & ElementTypeMap<Stored, SupportType>::operator()(const SupportType & type,
const GhostType & ghost_type) {
return this->getData(ghost_type)[type];
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline Stored & ElementTypeMap<Stored, SupportType>::operator()(const Stored & insert,
const SupportType & type,
const GhostType & ghost_type) {
typename DataMap::iterator it =
this->getData(ghost_type).find(type);
if(it != this->getData(ghost_type).end()) {
AKANTU_EXCEPTION("Element of type "
<< ElementTypeMap::printType(type, ghost_type)
<< " already in this ElementTypeMap<"
<< debug::demangle(typeid(Stored).name()) << "> class");
} else {
DataMap & data = this->getData(ghost_type);
const std::pair<typename DataMap::iterator, bool> & res =
data.insert(std::pair<ElementType, Stored>(type, insert));
it = res.first;
}
return it->second;
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::DataMap &
ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) {
if(ghost_type == _not_ghost) return data;
else return ghost_data;
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline const typename ElementTypeMap<Stored, SupportType>::DataMap &
ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) const {
if(ghost_type == _not_ghost) return data;
else return ghost_data;
}
/* -------------------------------------------------------------------------- */
/// Works only if stored is a pointer to a class with a printself method
template<class Stored, typename SupportType>
void ElementTypeMap<Stored, SupportType>::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "ElementTypeMap<" << debug::demangle(typeid(Stored).name()) << "> [" << std::endl;
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
const DataMap & data = getData(gt);
typename DataMap::const_iterator it;
for(it = data.begin(); it != data.end(); ++it) {
stream << space << space << ElementTypeMap::printType(it->first, gt) << std::endl;
}
}
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
ElementTypeMap<Stored, SupportType>::ElementTypeMap() {
AKANTU_DEBUG_IN();
// std::stringstream sstr;
// if(parent_id != "") sstr << parent_id << ":";
// sstr << id;
// this->id = sstr.str();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
ElementTypeMap<Stored, SupportType>::~ElementTypeMap() {
}
/* -------------------------------------------------------------------------- */
/* ElementTypeMapArray */
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline Array<T> & ElementTypeMapArray<T, SupportType>::alloc(UInt size,
UInt nb_component,
const SupportType & type,
const GhostType & ghost_type,
const T & default_value) {
std::string ghost_id = "";
if (ghost_type == _ghost) ghost_id = ":ghost";
Array<T> * tmp;
typename ElementTypeMapArray<T, SupportType>::DataMap::iterator it =
this->getData(ghost_type).find(type);
if(it == this->getData(ghost_type).end()) {
std::stringstream sstr; sstr << this->id << ":" << type << ghost_id;
tmp = &(Memory::alloc<T>(sstr.str(), size,
nb_component, default_value));
std::stringstream sstrg; sstrg << ghost_type;
//tmp->setTag(sstrg.str());
this->getData(ghost_type)[type] = tmp;
} else {
AKANTU_DEBUG_INFO("The vector " << this->id << this->printType(type, ghost_type)
<< " already exists, it is resized instead of allocated.");
tmp = it->second;
it->second->resize(size);
}
return *tmp;
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline void ElementTypeMapArray<T, SupportType>::alloc(UInt size,
UInt nb_component,
const SupportType & type,
const T & default_value) {
this->alloc(size, nb_component, type, _not_ghost, default_value);
this->alloc(size, nb_component, type, _ghost, default_value);
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline void ElementTypeMapArray<T, SupportType>::free() {
AKANTU_DEBUG_IN();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
DataMap & data = this->getData(gt);
typename DataMap::const_iterator it;
for(it = data.begin(); it != data.end(); ++it) {
dealloc(it->second->getID());
}
data.clear();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline void ElementTypeMapArray<T, SupportType>::clear() {
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
DataMap & data = this->getData(gt);
typename DataMap::const_iterator it;
for(it = data.begin(); it != data.end(); ++it) {
it->second->clear();
}
}
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline const Array<T> & ElementTypeMapArray<T, SupportType>::operator()(const SupportType & type,
const GhostType & ghost_type) const {
typename ElementTypeMapArray<T, SupportType>::DataMap::const_iterator it =
this->getData(ghost_type).find(type);
if(it == this->getData(ghost_type).end())
AKANTU_EXCEPTION("No element of type "
<< ElementTypeMapArray::printType(type, ghost_type)
<< " in this const ElementTypeMapArray<"
<< debug::demangle(typeid(T).name()) << "> class(\""
<< this->id << "\")");
return *(it->second);
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline Array<T> & ElementTypeMapArray<T, SupportType>::operator()(const SupportType & type,
const GhostType & ghost_type) {
typename ElementTypeMapArray<T, SupportType>::DataMap::iterator it =
this->getData(ghost_type).find(type);
if(it == this->getData(ghost_type).end())
AKANTU_EXCEPTION("No element of type "
<< ElementTypeMapArray::printType(type, ghost_type)
<< " in this ElementTypeMapArray<"
<< debug::demangle(typeid(T).name()) << "> class (\""
<< this->id << "\")");
return *(it->second);
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline void ElementTypeMapArray<T, SupportType>::setArray(const SupportType & type,
const GhostType & ghost_type,
const Array<T> & vect) {
typename ElementTypeMapArray<T, SupportType>::DataMap::iterator it =
this->getData(ghost_type).find(type);
if(AKANTU_DEBUG_TEST(dblWarning) && it != this->getData(ghost_type).end() && it->second != &vect) {
AKANTU_DEBUG_WARNING("The Array " << this->printType(type, ghost_type)
<< " is already registred, this call can lead to a memory leak.");
}
this->getData(ghost_type)[type] = &(const_cast<Array<T> &>(vect));
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline void ElementTypeMapArray<T, SupportType>::onElementsRemoved(const ElementTypeMapArray<UInt> & new_numbering) {
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
ElementTypeMapArray<UInt>::type_iterator it = new_numbering.firstType(_all_dimensions, gt, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end = new_numbering.lastType(_all_dimensions, gt, _ek_not_defined);
for (; it != end; ++it) {
SupportType type = *it;
if(this->exists(type, gt)){
const Array<UInt> & renumbering = new_numbering(type, gt);
if (renumbering.getSize() == 0) continue;
Array<T> & vect = this->operator()(type, gt);
UInt nb_component = vect.getNbComponent();
Array<T> tmp(renumbering.getSize(), nb_component);
UInt new_size = 0;
for (UInt i = 0; i < vect.getSize(); ++i) {
UInt new_i = renumbering(i);
if(new_i != UInt(-1)) {
memcpy(tmp.storage() + new_i * nb_component,
vect.storage() + i *nb_component,
nb_component * sizeof(T));
++new_size;
}
}
tmp.resize(new_size);
vect.copy(tmp);
}
}
}
}
/* -------------------------------------------------------------------------- */
template<typename T, typename SupportType>
void ElementTypeMapArray<T, SupportType>::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "ElementTypeMapArray<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
const DataMap & data = this->getData(gt);
typename DataMap::const_iterator it;
for(it = data.begin(); it != data.end(); ++it) {
stream << space << space << ElementTypeMapArray::printType(it->first, gt) << " [" << std::endl;
it->second->printself(stream, indent + 3);
stream << space << space << " ]" << std::endl;
}
}
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
/* SupportType Iterator */
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(DataMapIterator & list_begin,
DataMapIterator & list_end,
UInt dim, ElementKind ek) :
list_begin(list_begin), list_end(list_end), dim(dim), kind(ek) {
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(const type_iterator & it) :
list_begin(it.list_begin), list_end(it.list_end), dim(it.dim), kind(it.kind) {
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
typename ElementTypeMap<Stored, SupportType>::type_iterator & ElementTypeMap<Stored, SupportType>::type_iterator::operator=(const type_iterator & it) {
if(this != &it) {
list_begin = it.list_begin;
list_end = it.list_end;
dim = it.dim;
kind = it.kind;
}
return *this;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
ElementTypeMap<Stored, SupportType>::type_iterator::operator*() {
return list_begin->first;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
ElementTypeMap<Stored, SupportType>::type_iterator::operator*() const {
return list_begin->first;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator &
ElementTypeMap<Stored, SupportType>::type_iterator::operator++() {
++list_begin;
while((list_begin != list_end) &&
(((dim != _all_dimensions) && (dim != Mesh::getSpatialDimension(list_begin->first))) ||
((kind != _ek_not_defined) && (kind != Mesh::getKind(list_begin->first)))
)
)
++list_begin;
return *this;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
typename ElementTypeMap<Stored, SupportType>::type_iterator ElementTypeMap<Stored, SupportType>::type_iterator::operator++(int) {
type_iterator tmp(*this);
operator++();
return tmp;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline bool ElementTypeMap<Stored, SupportType>::type_iterator::operator==(const type_iterator & other) const {
return this->list_begin == other.list_begin;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline bool ElementTypeMap<Stored, SupportType>::type_iterator::operator!=(const type_iterator & other) const {
return this->list_begin != other.list_begin;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator
ElementTypeMap<Stored, SupportType>::firstType(UInt dim, GhostType ghost_type, ElementKind kind) const {
typename DataMap::const_iterator b,e;
b = getData(ghost_type).begin();
e = getData(ghost_type).end();
// loop until the first valid type
while((b != e) &&
(((dim != _all_dimensions) && (dim != Mesh::getSpatialDimension(b->first))) ||
((kind != _ek_not_defined) && (kind != Mesh::getKind(b->first)))))
++b;
return typename ElementTypeMap<Stored, SupportType>::type_iterator(b, e, dim, kind);
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator
ElementTypeMap<Stored, SupportType>::lastType(UInt dim, GhostType ghost_type, ElementKind kind) const {
typename DataMap::const_iterator e;
e = getData(ghost_type).end();
return typename ElementTypeMap<Stored, SupportType>::type_iterator(e, e, dim, kind);
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator
template <class Stored, typename SupportType>
inline std::ostream & operator <<(std::ostream & stream, const ElementTypeMap<Stored, SupportType> & _this)
{
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__ */
diff --git a/src/mesh/group_manager.cc b/src/mesh/group_manager.cc
index a2e872046..3f992471c 100644
--- a/src/mesh/group_manager.cc
+++ b/src/mesh/group_manager.cc
@@ -1,1014 +1,1015 @@
/**
* @file group_manager.cc
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@gmail.com>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Mon Aug 17 2015
*
* @brief Stores information about ElementGroup and NodeGroup
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "group_manager.hh"
#include "mesh.hh"
#include "aka_csr.hh"
#include "mesh_utils.hh"
#include "element_group.hh"
#include "node_group.hh"
#include "data_accessor.hh"
#include "distributed_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#include <sstream>
#include <algorithm>
#include <iterator>
#include <list>
#include <queue>
#include <numeric>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
GroupManager::GroupManager(const Mesh & mesh,
const ID & id,
const MemoryID & mem_id) : id(id),
memory_id(mem_id),
mesh(mesh) {
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
GroupManager::~GroupManager() {
ElementGroups::iterator eit = element_groups.begin();
ElementGroups::iterator eend = element_groups.end();
for(; eit != eend ; ++eit) delete (eit->second);
NodeGroups::iterator nit = node_groups.begin();
NodeGroups::iterator nend = node_groups.end();
for(; nit != nend ; ++nit) delete (nit->second);
}
/* -------------------------------------------------------------------------- */
NodeGroup & GroupManager::createNodeGroup(const std::string & group_name,
bool replace_group) {
AKANTU_DEBUG_IN();
NodeGroups::iterator it = node_groups.find(group_name);
if(it != node_groups.end()) {
if (replace_group) {
it->second->empty();
AKANTU_DEBUG_OUT();
return *(it->second);
}
else
AKANTU_EXCEPTION("Trying to create a node group that already exists:" << group_name);
}
std::stringstream sstr;
sstr << this->id << ":" << group_name << "_node_group";
NodeGroup * node_group = new NodeGroup(group_name,
mesh,
sstr.str(),
memory_id);
node_groups[group_name] = node_group;
AKANTU_DEBUG_OUT();
return *node_group;
}
/* -------------------------------------------------------------------------- */
template<typename T>
NodeGroup & GroupManager::createFilteredNodeGroup(const std::string & group_name,
const NodeGroup & source_node_group,
T & filter) {
AKANTU_DEBUG_IN();
NodeGroup & node_group = this->createNodeGroup(group_name);
node_group.append(source_node_group);
if (T::type == FilterFunctor::_node_filter_functor) {
node_group.applyNodeFilter(filter);
}
else {
AKANTU_DEBUG_ERROR("ElementFilter cannot be applied to NodeGroup yet."
<< " Needs to be implemented.");
}
AKANTU_DEBUG_OUT();
return node_group;
}
/* -------------------------------------------------------------------------- */
void GroupManager::destroyNodeGroup(const std::string & group_name) {
AKANTU_DEBUG_IN();
NodeGroups::iterator nit = node_groups.find(group_name);
NodeGroups::iterator nend = node_groups.end();
if (nit != nend) {
delete (nit->second);
node_groups.erase(nit);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
UInt dimension,
bool replace_group) {
AKANTU_DEBUG_IN();
NodeGroup & new_node_group = createNodeGroup(group_name + "_nodes", replace_group);
ElementGroups::iterator it = element_groups.find(group_name);
if(it != element_groups.end()) {
if (replace_group) {
it->second->empty();
AKANTU_DEBUG_OUT();
return *(it->second);
}
else
AKANTU_EXCEPTION("Trying to create a element group that already exists:" << group_name);
}
std::stringstream sstr;
sstr << this->id << ":" << group_name << "_element_group";
ElementGroup * element_group = new ElementGroup(group_name, mesh, new_node_group,
dimension,
sstr.str(),
memory_id);
std::stringstream sstr_nodes;
sstr_nodes << group_name << "_nodes";
node_groups[sstr_nodes.str()] = &new_node_group;
element_groups[group_name] = element_group;
AKANTU_DEBUG_OUT();
return *element_group;
}
/* -------------------------------------------------------------------------- */
void GroupManager::destroyElementGroup(const std::string & group_name,
bool destroy_node_group) {
AKANTU_DEBUG_IN();
ElementGroups::iterator eit = element_groups.find(group_name);
ElementGroups::iterator eend = element_groups.end();
if (eit != eend) {
if (destroy_node_group)
destroyNodeGroup(eit->second->getNodeGroup().getName());
delete (eit->second);
element_groups.erase(eit);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GroupManager::destroyAllElementGroups(bool destroy_node_groups) {
AKANTU_DEBUG_IN();
ElementGroups::iterator eit = element_groups.begin();
ElementGroups::iterator eend = element_groups.end();
for(; eit != eend ; ++eit) {
if (destroy_node_groups)
destroyNodeGroup(eit->second->getNodeGroup().getName());
delete (eit->second);
}
element_groups.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
UInt dimension,
NodeGroup & node_group) {
AKANTU_DEBUG_IN();
if(element_groups.find(group_name) != element_groups.end())
AKANTU_EXCEPTION("Trying to create a element group that already exists:" << group_name);
ElementGroup * element_group = new ElementGroup(group_name, mesh, node_group,
dimension,
id + ":" + group_name + "_element_group",
memory_id);
element_groups[group_name] = element_group;
AKANTU_DEBUG_OUT();
return *element_group;
}
/* -------------------------------------------------------------------------- */
template <typename T>
ElementGroup & GroupManager::createFilteredElementGroup(const std::string & group_name,
UInt dimension,
const NodeGroup & node_group,
T & filter) {
AKANTU_DEBUG_IN();
ElementGroup * element_group = NULL;
if (T::type == FilterFunctor::_node_filter_functor) {
NodeGroup & filtered_node_group = this->createFilteredNodeGroup(group_name + "_nodes",
node_group,
filter);
element_group = &(this->createElementGroup(group_name,
dimension,
filtered_node_group));
}
else if (T::type == FilterFunctor::_element_filter_functor) {
AKANTU_DEBUG_ERROR("Cannot handle an ElementFilter yet. Needs to be implemented.");
}
AKANTU_DEBUG_OUT();
return *element_group;
}
/* -------------------------------------------------------------------------- */
class ClusterSynchronizer : public DataAccessor {
typedef std::set< std::pair<UInt, UInt> > DistantIDs;
public:
ClusterSynchronizer(GroupManager & group_manager,
UInt element_dimension,
std::string cluster_name_prefix,
ElementTypeMapArray<UInt> & element_to_fragment,
DistributedSynchronizer & distributed_synchronizer,
UInt nb_cluster) :
group_manager(group_manager),
element_dimension(element_dimension),
cluster_name_prefix(cluster_name_prefix),
element_to_fragment(element_to_fragment),
distributed_synchronizer(distributed_synchronizer),
nb_cluster(nb_cluster) { }
UInt synchronize() {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt rank = comm.whoAmI();
UInt nb_proc = comm.getNbProc();
/// find starting index to renumber local clusters
Array<UInt> nb_cluster_per_proc(nb_proc);
nb_cluster_per_proc(rank) = nb_cluster;
comm.allGather(nb_cluster_per_proc.storage(), 1);
starting_index = std::accumulate(nb_cluster_per_proc.begin(),
nb_cluster_per_proc.begin() + rank,
0);
UInt global_nb_fragment = std::accumulate(nb_cluster_per_proc.begin() + rank,
nb_cluster_per_proc.end(),
starting_index);
/// create the local to distant cluster pairs with neighbors
distributed_synchronizer.computeBufferSize(*this, _gst_gm_clusters);
distributed_synchronizer.asynchronousSynchronize(*this, _gst_gm_clusters);
distributed_synchronizer.waitEndSynchronize(*this, _gst_gm_clusters);
/// count total number of pairs
Array<int> nb_pairs(nb_proc); // This is potentially a bug for more than
// 2**31 pairs, but due to a all gatherv after
// it must be int to match MPI interfaces
nb_pairs(rank) = distant_ids.size();
comm.allGather(nb_pairs.storage(), 1);
UInt total_nb_pairs = std::accumulate(nb_pairs.begin(), nb_pairs.end(), 0);
/// generate pairs global array
UInt local_pair_index = std::accumulate(nb_pairs.storage(),
nb_pairs.storage() + rank, 0);
Array<UInt> total_pairs(total_nb_pairs, 2);
DistantIDs::iterator ids_it = distant_ids.begin();
DistantIDs::iterator ids_end = distant_ids.end();
for (; ids_it != ids_end; ++ids_it, ++local_pair_index) {
total_pairs(local_pair_index, 0) = ids_it->first;
total_pairs(local_pair_index, 1) = ids_it->second;
}
/// communicate pairs to all processors
nb_pairs *= 2;
comm.allGatherV(total_pairs.storage(), nb_pairs.storage());
/// renumber clusters
/// generate fragment list
std::vector< std::set<UInt> > global_clusters;
UInt total_nb_cluster = 0;
Array<bool> is_fragment_in_cluster(global_nb_fragment, 1, false);
std::queue<UInt> fragment_check_list;
while (total_pairs.getSize() != 0) {
/// create a new cluster
++total_nb_cluster;
global_clusters.resize(total_nb_cluster);
std::set<UInt> & current_cluster = global_clusters[total_nb_cluster - 1];
UInt first_fragment = total_pairs(0, 0);
UInt second_fragment = total_pairs(0, 1);
total_pairs.erase(0);
fragment_check_list.push(first_fragment);
fragment_check_list.push(second_fragment);
while (!fragment_check_list.empty()) {
UInt current_fragment = fragment_check_list.front();
UInt * total_pairs_end = total_pairs.storage() + total_pairs.getSize() * 2;
UInt * fragment_found = std::find(total_pairs.storage(),
total_pairs_end,
current_fragment);
if (fragment_found != total_pairs_end) {
UInt position = fragment_found - total_pairs.storage();
UInt pair = position / 2;
UInt other_index = (position + 1) % 2;
fragment_check_list.push(total_pairs(pair, other_index));
total_pairs.erase(pair);
}
else {
fragment_check_list.pop();
current_cluster.insert(current_fragment);
is_fragment_in_cluster(current_fragment) = true;
}
}
}
/// add to FragmentToCluster all local fragments
for (UInt c = 0; c < global_nb_fragment; ++c) {
if (!is_fragment_in_cluster(c)) {
++total_nb_cluster;
global_clusters.resize(total_nb_cluster);
std::set<UInt> & current_cluster = global_clusters[total_nb_cluster - 1];
current_cluster.insert(c);
}
}
/// reorganize element groups to match global clusters
for (UInt c = 0; c < global_clusters.size(); ++c) {
/// create new element group corresponding to current cluster
std::stringstream sstr;
sstr << cluster_name_prefix << "_" << c;
ElementGroup & cluster = group_manager.createElementGroup(sstr.str(),
element_dimension,
true);
std::set<UInt>::iterator it = global_clusters[c].begin();
std::set<UInt>::iterator end = global_clusters[c].end();
/// append to current element group all fragments that belong to
/// the same cluster if they exist
for (; it != end; ++it) {
Int local_index = *it - starting_index;
if (local_index < 0 || local_index >= Int(nb_cluster)) continue;
std::stringstream tmp_sstr;
tmp_sstr << "tmp_" << cluster_name_prefix << "_" << local_index;
GroupManager::element_group_iterator eg_it
= group_manager.element_group_find(tmp_sstr.str());
AKANTU_DEBUG_ASSERT(eg_it != group_manager.element_group_end(),
"Temporary fragment \""<< tmp_sstr.str() << "\" not found");
cluster.append(*(eg_it->second));
group_manager.destroyElementGroup(tmp_sstr.str(), true);
}
}
return total_nb_cluster;
}
private:
/// functions for parallel communications
inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
if (tag == _gst_gm_clusters)
return elements.getSize() * sizeof(UInt);
return 0;
}
inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
if (tag != _gst_gm_clusters) return;
Array<Element>::const_iterator<> el_it = elements.begin();
Array<Element>::const_iterator<> el_end = elements.end();
for (; el_it != el_end; ++el_it) {
const Element & el = *el_it;
/// for each element pack its global cluster index
buffer << element_to_fragment(el.type, el.ghost_type)(el.element) + starting_index;
}
}
inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
if (tag != _gst_gm_clusters) return;
Array<Element>::const_iterator<> el_it = elements.begin();
Array<Element>::const_iterator<> el_end = elements.end();
for (; el_it != el_end; ++el_it) {
UInt distant_cluster;
buffer >> distant_cluster;
const Element & el = *el_it;
UInt local_cluster = element_to_fragment(el.type, el.ghost_type)(el.element) + starting_index;
distant_ids.insert(std::make_pair(local_cluster, distant_cluster));
}
}
private:
GroupManager & group_manager;
UInt element_dimension;
std::string cluster_name_prefix;
ElementTypeMapArray<UInt> & element_to_fragment;
DistributedSynchronizer & distributed_synchronizer;
UInt nb_cluster;
DistantIDs distant_ids;
UInt starting_index;
};
/* -------------------------------------------------------------------------- */
/// \todo this function doesn't work in 1D
UInt GroupManager::createBoundaryGroupFromGeometry() {
UInt spatial_dimension = mesh.getSpatialDimension();
return createClusters(spatial_dimension - 1, "boundary");
}
/* -------------------------------------------------------------------------- */
//// \todo if needed element list construction can be optimized by
//// templating the filter class
UInt GroupManager::createClusters(UInt element_dimension,
std::string cluster_name_prefix,
const GroupManager::ClusteringFilter & filter,
DistributedSynchronizer * distributed_synchronizer,
Mesh * mesh_facets) {
AKANTU_DEBUG_IN();
UInt nb_proc = StaticCommunicator::getStaticCommunicator().getNbProc();
std::string tmp_cluster_name_prefix = cluster_name_prefix;
ElementTypeMapArray<UInt> * element_to_fragment = NULL;
if (nb_proc > 1 && distributed_synchronizer) {
element_to_fragment = new ElementTypeMapArray<UInt>;
mesh.initElementTypeMapArray(*element_to_fragment, 1, element_dimension,
false, _ek_not_defined, true);
tmp_cluster_name_prefix = "tmp_" + tmp_cluster_name_prefix;
}
/// Get facets
bool mesh_facets_created = false;
if (!mesh_facets && element_dimension > 0) {
mesh_facets = new Mesh(mesh.getSpatialDimension(),
mesh.getNodes().getID(),
"mesh_facets_for_clusters");
mesh_facets->defineMeshParent(mesh);
MeshUtils::buildAllFacets(mesh, *mesh_facets,
element_dimension,
element_dimension - 1,
distributed_synchronizer);
}
ElementTypeMapArray<bool> seen_elements("seen_elements");
mesh.initElementTypeMapArray(seen_elements, 1, element_dimension,
false, _ek_not_defined, true);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Element el;
el.ghost_type = ghost_type;
Mesh::type_iterator type_it = mesh.firstType(element_dimension,
ghost_type, _ek_not_defined);
Mesh::type_iterator type_end = mesh.lastType (element_dimension,
ghost_type, _ek_not_defined);
for (; type_it != type_end; ++type_it) {
el.type = *type_it;
el.kind = Mesh::getKind(*type_it);
UInt nb_element = mesh.getNbElement(*type_it, ghost_type);
Array<bool> & seen_elements_array = seen_elements(el.type, ghost_type);
for (UInt e = 0; e < nb_element; ++e) {
el.element = e;
if (!filter(el))
seen_elements_array(e) = true;
}
}
}
Array<bool> checked_node(mesh.getNbNodes(), 1, false);
UInt nb_cluster = 0;
/// keep looping until all elements are seen
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Element uns_el;
uns_el.ghost_type = ghost_type;
Mesh::type_iterator type_it = mesh.firstType(element_dimension,
ghost_type,
_ek_not_defined);
Mesh::type_iterator type_end = mesh.lastType(element_dimension,
ghost_type,
_ek_not_defined);
for (; type_it != type_end; ++type_it) {
uns_el.type = *type_it;
Array<bool> & seen_elements_vec = seen_elements(uns_el.type, uns_el.ghost_type);
for (UInt e = 0; e < seen_elements_vec.getSize(); ++e) {
// skip elements that have been already seen
if (seen_elements_vec(e) == true) continue;
// set current element
uns_el.element = e;
seen_elements_vec(e) = true;
/// create a new cluster
std::stringstream sstr;
sstr << tmp_cluster_name_prefix << "_" << nb_cluster;
ElementGroup & cluster = createElementGroup(sstr.str(),
element_dimension,
true);
++nb_cluster;
// point element are cluster by themself
if(element_dimension == 0) {
cluster.add(uns_el);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(uns_el.type);
Vector<UInt> connect =
mesh.getConnectivity(uns_el.type, uns_el.ghost_type).begin(nb_nodes_per_element)[uns_el.element];
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
/// add element's nodes to the cluster
UInt node = connect[n];
if (!checked_node(node)) {
cluster.addNode(node);
checked_node(node) = true;
}
}
continue;
}
std::queue<Element> element_to_add;
element_to_add.push(uns_el);
/// keep looping until current cluster is complete (no more
/// connected elements)
while(!element_to_add.empty()) {
/// take first element and erase it in the queue
Element el = element_to_add.front();
element_to_add.pop();
/// if parallel, store cluster index per element
if (nb_proc > 1 && distributed_synchronizer)
(*element_to_fragment)(el.type, el.ghost_type)(el.element) = nb_cluster - 1;
/// add current element to the cluster
cluster.add(el);
const Array<Element> & element_to_facet
= mesh_facets->getSubelementToElement(el.type, el.ghost_type);
UInt nb_facet_per_element = element_to_facet.getNbComponent();
for (UInt f = 0; f < nb_facet_per_element; ++f) {
const Element & facet = element_to_facet(el.element, f);
if (facet == ElementNull) continue;
const std::vector<Element> & connected_elements
= mesh_facets->getElementToSubelement(facet.type, facet.ghost_type)(facet.element);
for (UInt elem = 0; elem < connected_elements.size(); ++elem) {
const Element & check_el = connected_elements[elem];
// check if this element has to be skipped
if (check_el == ElementNull || check_el == el) continue;
Array<bool> & seen_elements_vec_current
= seen_elements(check_el.type, check_el.ghost_type);
if (seen_elements_vec_current(check_el.element) == false) {
seen_elements_vec_current(check_el.element) = true;
element_to_add.push(check_el);
}
}
}
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
Vector<UInt> connect =
mesh.getConnectivity(el.type, el.ghost_type).begin(nb_nodes_per_element)[el.element];
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
/// add element's nodes to the cluster
UInt node = connect[n];
if (!checked_node(node)) {
cluster.addNode(node, false);
checked_node(node) = true;
}
}
}
}
}
}
if (nb_proc > 1 && distributed_synchronizer) {
ClusterSynchronizer cluster_synchronizer(*this, element_dimension,
cluster_name_prefix,
*element_to_fragment,
*distributed_synchronizer,
nb_cluster);
nb_cluster = cluster_synchronizer.synchronize();
delete element_to_fragment;
}
if (mesh_facets_created)
delete mesh_facets;
if(mesh.isDistributed())
this->synchronizeGroupNames();
AKANTU_DEBUG_OUT();
return nb_cluster;
}
/* -------------------------------------------------------------------------- */
template<typename T>
void GroupManager::createGroupsFromMeshData(const std::string & dataset_name) {
std::set<std::string> group_names;
const ElementTypeMapArray<T> & datas = mesh.getData<T>(dataset_name);
typedef typename ElementTypeMapArray<T>::type_iterator type_iterator;
std::map<std::string, UInt> group_dim;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
type_iterator type_it = datas.firstType(_all_dimensions, *gt);
type_iterator type_end = datas.lastType(_all_dimensions, *gt);
for (; type_it != type_end; ++type_it) {
const Array<T> & dataset = datas(*type_it, *gt);
UInt nb_element = mesh.getNbElement(*type_it, *gt);
AKANTU_DEBUG_ASSERT(dataset.getSize() == nb_element,
"Not the same number of elements ("<< *type_it << ":" << *gt <<
") in the map from MeshData (" << dataset.getSize() << ") "
<< dataset_name <<" and in the mesh (" << nb_element << ")!");
for(UInt e(0); e < nb_element; ++e) {
std::stringstream sstr; sstr << dataset(e);
std::string gname = sstr.str();
group_names.insert(gname);
std::map<std::string, UInt>::iterator it = group_dim.find(gname);
if(it == group_dim.end()) {
group_dim[gname] = mesh.getSpatialDimension(*type_it);
} else {
it->second = std::max(it->second, mesh.getSpatialDimension(*type_it));
}
}
}
}
std::set<std::string>::iterator git = group_names.begin();
std::set<std::string>::iterator gend = group_names.end();
for (;git != gend; ++git) createElementGroup(*git, group_dim[*git]);
if(mesh.isDistributed())
this->synchronizeGroupNames();
Element el;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
el.ghost_type = *gt;
type_iterator type_it = datas.firstType(_all_dimensions, *gt);
type_iterator type_end = datas.lastType(_all_dimensions, *gt);
for (; type_it != type_end; ++type_it) {
el.type = *type_it;
const Array<T> & dataset = datas(*type_it, *gt);
UInt nb_element = mesh.getNbElement(*type_it, *gt);
AKANTU_DEBUG_ASSERT(dataset.getSize() == nb_element,
"Not the same number of elements in the map from MeshData and in the mesh!");
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(el.type);
Array<UInt>::const_iterator< Vector<UInt> > cit =
mesh.getConnectivity(*type_it, *gt).begin(nb_nodes_per_element);
for(UInt e(0); e < nb_element; ++e, ++cit) {
el.element = e;
std::stringstream sstr; sstr << dataset(e);
ElementGroup & group = getElementGroup(sstr.str());
group.add(el, false, false);
const Vector<UInt> & connect = *cit;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connect[n];
group.addNode(node, false);
}
}
}
}
git = group_names.begin();
for (;git != gend; ++git) {
getElementGroup(*git).optimize();
}
}
template void GroupManager::createGroupsFromMeshData<std::string>(const std::string & dataset_name);
template void GroupManager::createGroupsFromMeshData<UInt>(const std::string & dataset_name);
/* -------------------------------------------------------------------------- */
void GroupManager::createElementGroupFromNodeGroup(const std::string & name,
const std::string & node_group_name,
UInt dimension) {
NodeGroup & node_group = getNodeGroup(node_group_name);
ElementGroup & group = createElementGroup(name, dimension, node_group);
group.fillFromNodeGroup();
}
/* -------------------------------------------------------------------------- */
void GroupManager::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "GroupManager [" << std::endl;
std::set<std::string> node_group_seen;
for(const_element_group_iterator it(element_group_begin()); it != element_group_end(); ++it) {
it->second->printself(stream, indent + 1);
node_group_seen.insert(it->second->getNodeGroup().getName());
}
for(const_node_group_iterator it(node_group_begin()); it != node_group_end(); ++it) {
if(node_group_seen.find(it->second->getName()) == node_group_seen.end())
it->second->printself(stream, indent + 1);
}
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
UInt GroupManager::getNbElementGroups(UInt dimension) const {
if(dimension == _all_dimensions) return element_groups.size();
ElementGroups::const_iterator it = element_groups.begin();
ElementGroups::const_iterator end = element_groups.end();
UInt count = 0;
for(;it != end; ++it) count += (it->second->getDimension() == dimension);
return count;
}
/* -------------------------------------------------------------------------- */
void GroupManager::checkAndAddGroups(CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
UInt nb_node_group; buffer >> nb_node_group;
AKANTU_DEBUG_INFO("Received " << nb_node_group << " node group names");
for (UInt ng = 0; ng < nb_node_group; ++ng) {
std::string node_group_name;
buffer >> node_group_name;
if(node_groups.find(node_group_name) == node_groups.end()) {
this->createNodeGroup(node_group_name);
}
AKANTU_DEBUG_INFO("Received node goup name: " << node_group_name);
}
UInt nb_element_group; buffer >> nb_element_group;
AKANTU_DEBUG_INFO("Received " << nb_element_group << " element group names");
for (UInt eg = 0; eg < nb_element_group; ++eg) {
std::string element_group_name; buffer >> element_group_name;
std::string node_group_name; buffer >> node_group_name;
UInt dim; buffer >> dim;
AKANTU_DEBUG_INFO("Received element group name: " << element_group_name
<< " corresponding to a "
<< Int(dim) << "D group with node group "
<< node_group_name);
NodeGroup & node_group = *node_groups[node_group_name];
if(element_groups.find(element_group_name) == element_groups.end()) {
this->createElementGroup(element_group_name, dim, node_group);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GroupManager::fillBufferWithGroupNames(DynamicCommunicationBuffer & comm_buffer) const {
AKANTU_DEBUG_IN();
// packing node group names;
UInt nb_groups = this->node_groups.size();
comm_buffer << nb_groups;
AKANTU_DEBUG_INFO("Sending " << nb_groups << " node group names");
NodeGroups::const_iterator nnames_it = node_groups.begin();
NodeGroups::const_iterator nnames_end = node_groups.end();
for (; nnames_it != nnames_end; ++nnames_it) {
std::string node_group_name = nnames_it->first;
comm_buffer << node_group_name;
AKANTU_DEBUG_INFO("Sending node goupe name: " << node_group_name);
}
// packing element group names with there associated node group name
nb_groups = this->element_groups.size();
comm_buffer << nb_groups;
AKANTU_DEBUG_INFO("Sending " << nb_groups << " element group names");
ElementGroups::const_iterator gnames_it = this->element_groups.begin();
ElementGroups::const_iterator gnames_end = this->element_groups.end();
for (; gnames_it != gnames_end; ++gnames_it) {
ElementGroup & element_group = *(gnames_it->second);
std::string element_group_name = gnames_it->first;
std::string node_group_name = element_group.getNodeGroup().getName();
UInt dim = element_group.getDimension();
comm_buffer << element_group_name;
comm_buffer << node_group_name;
comm_buffer << dim;
AKANTU_DEBUG_INFO("Sending element group name: " << element_group_name
<< " corresponding to a "
<< Int(dim) << "D group with the node group "
<< node_group_name);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GroupManager::synchronizeGroupNames() {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
if(nb_proc == 1) return;
if(my_rank == 0) {
for (UInt p = 1; p < nb_proc; ++p) {
CommunicationStatus status;
comm.probe<char>(p, p, status);
AKANTU_DEBUG_INFO("Got " << printMemorySize<char>(status.getSize()) << " from proc " << p);
CommunicationBuffer recv_buffer(status.getSize());
comm.receive(recv_buffer.storage(), recv_buffer.getSize(), p, p);
this->checkAndAddGroups(recv_buffer);
}
DynamicCommunicationBuffer comm_buffer;
this->fillBufferWithGroupNames(comm_buffer);
UInt buffer_size = comm_buffer.getSize();
comm.broadcast(&buffer_size, 1, 0);
AKANTU_DEBUG_INFO("Initiating broadcast with " << printMemorySize<char>(comm_buffer.getSize()));
comm.broadcast(comm_buffer.storage(), buffer_size, 0);
} else {
DynamicCommunicationBuffer comm_buffer;
this->fillBufferWithGroupNames(comm_buffer);
AKANTU_DEBUG_INFO("Sending " << printMemorySize<char>(comm_buffer.getSize()) << " to proc " << 0);
comm.send(comm_buffer.storage(), comm_buffer.getSize(), 0, my_rank);
UInt buffer_size = 0;
comm.broadcast(&buffer_size, 1, 0);
AKANTU_DEBUG_INFO("Receiving broadcast with " << printMemorySize<char>(comm_buffer.getSize()));
CommunicationBuffer recv_buffer(buffer_size);
comm.broadcast(recv_buffer.storage(), recv_buffer.getSize(), 0);
this->checkAndAddGroups(recv_buffer);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
const ElementGroup & GroupManager::getElementGroup(const std::string & name) const {
const_element_group_iterator it = element_group_find(name);
if(it == element_group_end()) {
AKANTU_EXCEPTION("There are no element groups named " << name
<< " associated to the group manager: " << id);
}
return *(it->second);
}
/* -------------------------------------------------------------------------- */
ElementGroup & GroupManager::getElementGroup(const std::string & name) {
element_group_iterator it = element_group_find(name);
if(it == element_group_end()) {
AKANTU_EXCEPTION("There are no element groups named " << name
<< " associated to the group manager: " << id);
}
return *(it->second);
}
/* -------------------------------------------------------------------------- */
const NodeGroup & GroupManager::getNodeGroup(const std::string & name) const {
const_node_group_iterator it = node_group_find(name);
if(it == node_group_end()) {
AKANTU_EXCEPTION("There are no node groups named " << name
<< " associated to the group manager: " << id);
}
return *(it->second);
}
/* -------------------------------------------------------------------------- */
NodeGroup & GroupManager::getNodeGroup(const std::string & name) {
node_group_iterator it = node_group_find(name);
if(it == node_group_end()) {
AKANTU_EXCEPTION("There are no node groups named " << name
<< " associated to the group manager: " << id);
}
return *(it->second);
}
__END_AKANTU__
diff --git a/src/mesh/group_manager.hh b/src/mesh/group_manager.hh
index c93556bf9..28d484fba 100644
--- a/src/mesh/group_manager.hh
+++ b/src/mesh/group_manager.hh
@@ -1,304 +1,305 @@
/**
* @file group_manager.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@gmail.com>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Mon Nov 16 2015
*
* @brief Stores information relevent to the notion of element and nodes groups.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_GROUP_MANAGER_HH__
#define __AKANTU_GROUP_MANAGER_HH__
#include <set>
#include "aka_common.hh"
#include "element_type_map.hh"
//#include "dumpable.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class FEM;
class ElementGroup;
class NodeGroup;
class Mesh;
class Element;
class DistributedSynchronizer;
template<bool> class CommunicationBufferTemplated;
namespace dumper {
class Field;
}
/* -------------------------------------------------------------------------- */
class GroupManager {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
private:
typedef std::map<std::string, ElementGroup *> ElementGroups;
typedef std::map<std::string, NodeGroup *> NodeGroups;
public:
typedef std::set<ElementType> GroupManagerTypeSet;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
GroupManager(const Mesh & mesh,
const ID & id = "group_manager",
const MemoryID & memory_id = 0);
virtual ~GroupManager();
/* ------------------------------------------------------------------------ */
/* Groups iterators */
/* ------------------------------------------------------------------------ */
public:
typedef NodeGroups::iterator node_group_iterator;
typedef ElementGroups::iterator element_group_iterator;
typedef NodeGroups::const_iterator const_node_group_iterator;
typedef ElementGroups::const_iterator const_element_group_iterator;
#ifndef SWIG
#define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(group_type, \
function, \
param_in, \
param_out) \
inline BOOST_PP_CAT(BOOST_PP_CAT(const_, group_type), _iterator) \
BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) const { \
return BOOST_PP_CAT(group_type, s).function(param_out); \
}; \
\
inline BOOST_PP_CAT(group_type, _iterator) \
BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) { \
return BOOST_PP_CAT(group_type, s).function(param_out); \
}
#define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(group_type, function) \
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(group_type, function, BOOST_PP_EMPTY(), BOOST_PP_EMPTY())
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, begin);
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, end );
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, begin);
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, end );
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(element_group, find, const std::string & name, name);
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(node_group, find, const std::string & name, name);
#endif
/* ------------------------------------------------------------------------ */
/* Clustering filter */
/* ------------------------------------------------------------------------ */
public:
class ClusteringFilter {
public:
virtual bool operator() (const Element &) const {
return true;
}
};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// create an empty node group
NodeGroup & createNodeGroup(const std::string & group_name,
bool replace_group = false);
/// create a node group from another node group but filtered
template <typename T>
NodeGroup & createFilteredNodeGroup(const std::string & group_name,
const NodeGroup & node_group,
T & filter);
/// destroy a node group
void destroyNodeGroup(const std::string & group_name);
/// create an element group and the associated node group
ElementGroup & createElementGroup(const std::string & group_name,
UInt dimension = _all_dimensions,
bool replace_group = false);
/// create an element group from another element group but filtered
template <typename T>
ElementGroup & createFilteredElementGroup(const std::string & group_name,
UInt dimension,
const NodeGroup & node_group,
T & filter);
/// destroy an element group and the associated node group
void destroyElementGroup(const std::string & group_name,
bool destroy_node_group = false);
/// destroy all element groups and the associated node groups
void destroyAllElementGroups(bool destroy_node_groups = false);
/// create a element group using an existing node group
ElementGroup & createElementGroup(const std::string & group_name,
UInt dimension,
NodeGroup & node_group);
/// create groups based on values stored in a given mesh data
template <typename T>
void createGroupsFromMeshData(const std::string & dataset_name);
/// create boundaries group by a clustering algorithm \todo extend to parallel
UInt createBoundaryGroupFromGeometry();
/// create element clusters for a given dimension
UInt createClusters(UInt element_dimension,
std::string cluster_name_prefix = "cluster",
const ClusteringFilter & filter = ClusteringFilter(),
DistributedSynchronizer * distributed_synchronizer = NULL,
Mesh * mesh_facets = NULL);
/// Create an ElementGroup based on a NodeGroup
void createElementGroupFromNodeGroup(const std::string & name,
const std::string & node_group,
UInt dimension = _all_dimensions);
virtual void printself(std::ostream & stream, int indent = 0) const;
/// this function insure that the group names are present on all processors
/// /!\ it is a SMP call
void synchronizeGroupNames();
/// register an elemental field to the given group name (overloading for ElementalPartionField)
#ifndef SWIG
template <typename T, template <bool> class dump_type>
inline dumper::Field * createElementalField(const ElementTypeMapArray<T> & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
/// register an elemental field to the given group name (overloading for ElementalField)
template <typename T, template <class> class ret_type, template <class,template <class> class,bool> class dump_type>
inline dumper::Field * createElementalField(const ElementTypeMapArray<T> & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
/// register an elemental field to the given group name (overloading for MaterialInternalField)
template <typename T,
/// type of InternalMaterialField
template<typename, bool filtered> class dump_type>
inline dumper::Field * createElementalField(const ElementTypeMapArray<T> & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem);
template <typename type, bool flag, template<class,bool> class ftype>
inline dumper::Field * createNodalField(const ftype<type,flag> * field,
const std::string & group_name,
UInt padding_size = 0);
template <typename type, bool flag, template<class,bool> class ftype>
inline dumper::Field * createStridedNodalField(const ftype<type,flag> * field,
const std::string & group_name,
UInt size, UInt stride,
UInt padding_size);
protected:
/// fill a buffer with all the group names
void fillBufferWithGroupNames(CommunicationBufferTemplated<false> & comm_buffer) const;
/// take a buffer and create the missing groups localy
void checkAndAddGroups(CommunicationBufferTemplated<true> & buffer);
/// register an elemental field to the given group name
template <class dump_type,typename field_type>
inline dumper::Field * createElementalField(const field_type & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem);
/// register an elemental field to the given group name
template <class dump_type,typename field_type>
inline dumper::Field * createElementalFilteredField(const field_type & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem);
#endif
/* ------------------------------------------------------------------------ */
/* Accessor */
/* ------------------------------------------------------------------------ */
public:
const ElementGroup & getElementGroup(const std::string & name) const;
const NodeGroup & getNodeGroup(const std::string & name) const;
ElementGroup & getElementGroup(const std::string & name);
NodeGroup & getNodeGroup(const std::string & name);
UInt getNbElementGroups(UInt dimension = _all_dimensions) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// id to create element and node groups
ID id;
/// memory_id to create element and node groups
MemoryID memory_id;
/// list of the node groups managed
NodeGroups node_groups;
/// list of the element groups managed
ElementGroups element_groups;
/// Mesh to which the element belongs
const Mesh & mesh;
};
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const GroupManager & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_GROUP_MANAGER_HH__ */
diff --git a/src/mesh/group_manager_inline_impl.cc b/src/mesh/group_manager_inline_impl.cc
index b5226c4e4..6a55937a2 100644
--- a/src/mesh/group_manager_inline_impl.cc
+++ b/src/mesh/group_manager_inline_impl.cc
@@ -1,222 +1,222 @@
/**
* @file group_manager_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Wed Sep 03 2014
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Tue Dec 08 2015
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_group.hh"
#include "dumper_field.hh"
#include "element_type_map_filter.hh"
#ifdef AKANTU_USE_IOHELPER
#include "dumper_nodal_field.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <typename T, template <bool> class dump_type>
dumper::Field * GroupManager
::createElementalField(const ElementTypeMapArray<T> & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem){
const ElementTypeMapArray<T> * field_ptr = &field;
if (field_ptr == NULL) return NULL;
if (group_name == "all")
return this->createElementalField< dump_type<false> >(field,group_name,
spatial_dimension,
kind,
nb_data_per_elem);
else
return this->createElementalFilteredField< dump_type<true> >(field,group_name,
spatial_dimension,
kind,
nb_data_per_elem);
}
/* -------------------------------------------------------------------------- */
template <typename T,
template <class> class T2,
template <class, template <class> class,bool> class dump_type>
dumper::Field * GroupManager
::createElementalField(const ElementTypeMapArray<T> & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem){
const ElementTypeMapArray<T> * field_ptr = &field;
if (field_ptr == NULL) return NULL;
if (group_name == "all")
return this->createElementalField< dump_type<T,T2,false> >(field,
group_name,
spatial_dimension,
kind,
nb_data_per_elem);
else
return this->createElementalFilteredField< dump_type<T,T2,true> >(field,
group_name,
spatial_dimension,
kind,
nb_data_per_elem);
}
/* -------------------------------------------------------------------------- */
template <typename T,
template<typename T2, bool filtered> class dump_type> ///< type of InternalMaterialField
dumper::Field * GroupManager::createElementalField(const ElementTypeMapArray<T> & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem) {
const ElementTypeMapArray<T> * field_ptr = &field;
if (field_ptr == NULL) return NULL;
if (group_name == "all")
return this->createElementalField< dump_type<T,false> >(field,
group_name,
spatial_dimension,
kind,
nb_data_per_elem);
else
return this->createElementalFilteredField< dump_type<T,true> >(field,
group_name,
spatial_dimension,
kind,
nb_data_per_elem);
}
/* -------------------------------------------------------------------------- */
template <typename dump_type,typename field_type>
dumper::Field * GroupManager::createElementalField(const field_type & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem) {
const field_type * field_ptr = &field;
if (field_ptr == NULL) return NULL;
if (group_name != "all") throw;
dumper::Field * dumper = new dump_type(field,spatial_dimension,_not_ghost,kind);
dumper->setNbDataPerElem(nb_data_per_elem);
return dumper;
}
/* -------------------------------------------------------------------------- */
template <typename dump_type,typename field_type>
dumper::Field * GroupManager::createElementalFilteredField(const field_type & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem) {
const field_type * field_ptr = &field;
if (field_ptr == NULL) return NULL;
if (group_name == "all") throw;
typedef typename field_type::type T;
ElementGroup & group = this->getElementGroup(group_name);
UInt dim = group.getDimension();
if (dim != spatial_dimension) throw;
const ElementTypeMapArray<UInt> & elemental_filter = group.getElements();
ElementTypeMapArrayFilter<T> * filtered =
new ElementTypeMapArrayFilter<T>(field,elemental_filter,nb_data_per_elem);
dumper::Field * dumper = new dump_type(*filtered,dim,_not_ghost,kind);
dumper->setNbDataPerElem(nb_data_per_elem);
return dumper;
}
/* -------------------------------------------------------------------------- */
template <typename type, bool flag, template<class,bool> class ftype>
dumper::Field * GroupManager::createNodalField(const ftype<type,flag> * field,
const std::string & group_name,
UInt padding_size){
if (field == NULL) return NULL;
if (group_name == "all"){
typedef typename dumper::NodalField<type, false> DumpType;
DumpType * dumper = new DumpType(*field, 0, 0, NULL);
dumper->setPadding(padding_size);
return dumper;
}
else {
ElementGroup & group = this->getElementGroup(group_name);
const Array<UInt> * nodal_filter = &(group.getNodes());
typedef typename dumper::NodalField<type, true> DumpType;
DumpType * dumper = new DumpType(*field, 0, 0, nodal_filter);
dumper->setPadding(padding_size);
return dumper;
}
return NULL;
}
/* -------------------------------------------------------------------------- */
template <typename type, bool flag, template<class,bool> class ftype>
dumper::Field * GroupManager::createStridedNodalField(const ftype<type,flag> * field,
const std::string & group_name,
UInt size, UInt stride,
UInt padding_size){
if (field == NULL) return NULL;
if (group_name == "all"){
typedef typename dumper::NodalField<type, false> DumpType;
DumpType * dumper = new DumpType(*field, size, stride, NULL);
dumper->setPadding(padding_size);
return dumper;
}
else {
ElementGroup & group = this->getElementGroup(group_name);
const Array<UInt> * nodal_filter = &(group.getNodes());
typedef typename dumper::NodalField<type, true> DumpType;
DumpType * dumper = new DumpType(*field, size, stride, nodal_filter);
dumper->setPadding(padding_size);
return dumper;
}
return NULL;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif
diff --git a/src/mesh/mesh.cc b/src/mesh/mesh.cc
index 139386376..5f2aebec3 100644
--- a/src/mesh/mesh.cc
+++ b/src/mesh/mesh.cc
@@ -1,507 +1,508 @@
/**
* @file mesh.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Fri Oct 02 2015
*
* @brief class handling meshes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <sstream>
#include "aka_config.hh"
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include "group_manager_inline_impl.cc"
#include "mesh_io.hh"
#include "element_class.hh"
#include "static_communicator.hh"
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
# include "dumper_field.hh"
# include "dumper_internal_material_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const Element ElementNull(_not_defined, 0);
/* -------------------------------------------------------------------------- */
void Element::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Element [" << type << ", " << element << ", " << ghost_type << "]";
}
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
GroupManager(*this, id + ":group_manager", memory_id),
nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
created_nodes(true),
connectivities("connectivities", id),
normals("normals", id),
spatial_dimension(spatial_dimension),
types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
ghost_types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
lower_bounds(spatial_dimension,0.),
upper_bounds(spatial_dimension,0.),
size(spatial_dimension, 0.),
local_lower_bounds(spatial_dimension,0.),
local_upper_bounds(spatial_dimension,0.),
mesh_data("mesh_data", id, memory_id),
mesh_facets(NULL) {
AKANTU_DEBUG_IN();
this->nodes = &(alloc<Real>(id + ":coordinates", 0, this->spatial_dimension));
nb_global_nodes = 0;
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension,
const ID & nodes_id,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
GroupManager(*this, id + ":group_manager", memory_id),
nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
created_nodes(false),
connectivities("connectivities", id),
normals("normals", id),
spatial_dimension(spatial_dimension),
types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
ghost_types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
lower_bounds(spatial_dimension,0.),
upper_bounds(spatial_dimension,0.),
size(spatial_dimension, 0.),
local_lower_bounds(spatial_dimension,0.),
local_upper_bounds(spatial_dimension,0.),
mesh_data("mesh_data", id, memory_id),
mesh_facets(NULL) {
AKANTU_DEBUG_IN();
this->nodes = &(getArray<Real>(nodes_id));
nb_global_nodes = nodes->getSize();
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension,
Array<Real> & nodes,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
GroupManager(*this, id + ":group_manager", memory_id),
nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
created_nodes(false),
connectivities("connectivities", id),
normals("normals", id),
spatial_dimension(spatial_dimension),
types_offsets(Array<UInt>(_max_element_type + 1, 1)),
ghost_types_offsets(Array<UInt>(_max_element_type + 1, 1)),
lower_bounds(spatial_dimension,0.),
upper_bounds(spatial_dimension,0.),
size(spatial_dimension, 0.),
local_lower_bounds(spatial_dimension,0.),
local_upper_bounds(spatial_dimension,0.),
mesh_data("mesh_data", id, memory_id),
mesh_facets(NULL) {
AKANTU_DEBUG_IN();
this->nodes = &(nodes);
nb_global_nodes = nodes.getSize();
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh & Mesh::initMeshFacets(const ID & id) {
AKANTU_DEBUG_IN();
if (!mesh_facets) {
mesh_facets = new Mesh(spatial_dimension,
*(this->nodes),
getID()+":"+id,
getMemoryID());
mesh_facets->mesh_parent = this;
mesh_facets->is_mesh_facets = true;
}
AKANTU_DEBUG_OUT();
return *mesh_facets;
}
/* -------------------------------------------------------------------------- */
void Mesh::defineMeshParent(const Mesh & mesh) {
AKANTU_DEBUG_IN();
this->mesh_parent = &mesh;
this->is_mesh_facets = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Mesh::init() {
this->is_mesh_facets = false;
this->mesh_parent = NULL;
this->is_distributed = false;
// computeBoundingBox();
}
/* -------------------------------------------------------------------------- */
Mesh::~Mesh() {
AKANTU_DEBUG_IN();
delete mesh_facets;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Mesh::read (const std::string & filename, const MeshIOType & mesh_io_type) {
MeshIO mesh_io;
mesh_io.read(filename, *this, mesh_io_type);
type_iterator it = this->firstType(spatial_dimension, _not_ghost, _ek_not_defined);
type_iterator last = this->lastType(spatial_dimension, _not_ghost, _ek_not_defined);
if(it == last) AKANTU_EXCEPTION("The mesh contained in the file " << filename
<< " does not seem to be of the good dimension."
<< " No element of dimension " << spatial_dimension
<< " where read.");
}
/* -------------------------------------------------------------------------- */
void Mesh::write(const std::string & filename, const MeshIOType & mesh_io_type) {
MeshIO mesh_io;
mesh_io.write(filename, *this, mesh_io_type);
}
/* -------------------------------------------------------------------------- */
void Mesh::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Mesh [" << std::endl;
stream << space << " + id : " << getID() << std::endl;
stream << space << " + spatial dimension : " << this->spatial_dimension << std::endl;
stream << space << " + nodes [" << std::endl;
nodes->printself(stream, indent+2);
stream << space << " + connectivities [" << std::endl;
connectivities.printself(stream, indent+2);
stream << space << " ]" << std::endl;
GroupManager::printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
void Mesh::computeBoundingBox(){
AKANTU_DEBUG_IN();
for (UInt k = 0; k < spatial_dimension; ++k) {
local_lower_bounds(k) = std::numeric_limits<double>::max();
local_upper_bounds(k) = - std::numeric_limits<double>::max();
}
for (UInt i = 0; i < nodes->getSize(); ++i) {
// if(!isPureGhostNode(i))
for (UInt k = 0; k < spatial_dimension; ++k) {
local_lower_bounds(k) = std::min(local_lower_bounds[k], (*nodes)(i, k));
local_upper_bounds(k) = std::max(local_upper_bounds[k], (*nodes)(i, k));
}
}
if (this->is_distributed) {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Real reduce_bounds[2 * spatial_dimension];
for (UInt k = 0; k < spatial_dimension; ++k) {
reduce_bounds[2*k ] = local_lower_bounds(k);
reduce_bounds[2*k + 1] = - local_upper_bounds(k);
}
comm.allReduce(reduce_bounds, 2 * spatial_dimension, _so_min);
for (UInt k = 0; k < spatial_dimension; ++k) {
lower_bounds(k) = reduce_bounds[2*k];
upper_bounds(k) = - reduce_bounds[2*k + 1];
}
}
else {
this->lower_bounds = this->local_lower_bounds;
this->upper_bounds = this->local_upper_bounds;
}
size = upper_bounds - lower_bounds;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T>
void Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
UInt nb_component,
UInt dim,
const bool & flag_nb_node_per_elem_multiply,
ElementKind element_kind,
bool size_to_nb_element) const {
AKANTU_DEBUG_IN();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
this->initElementTypeMapArray(vect, nb_component, dim, gt,
flag_nb_node_per_elem_multiply,
element_kind, size_to_nb_element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T>
void Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
UInt nb_component,
UInt dim,
GhostType gt,
const bool & flag_nb_node_per_elem_multiply,
ElementKind element_kind,
bool size_to_nb_element) const {
AKANTU_DEBUG_IN();
this->initElementTypeMapArray(vect,
nb_component,
dim,
gt,
T(),
flag_nb_node_per_elem_multiply,
element_kind,
size_to_nb_element);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T>
void Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
UInt nb_component,
UInt dim,
GhostType gt,
const T & default_value,
const bool & flag_nb_node_per_elem_multiply,
ElementKind element_kind,
bool size_to_nb_element) const {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = firstType(dim, gt, element_kind);
Mesh::type_iterator end = lastType(dim, gt, element_kind);
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_comp = nb_component;
if (flag_nb_node_per_elem_multiply) nb_comp *= Mesh::getNbNodesPerElement(*it);
UInt size = 0;
if (size_to_nb_element) size = this->getNbElement(type, gt);
vect.alloc(size, nb_comp, type, gt, default_value);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Mesh::initNormals() {
this->initElementTypeMapArray(normals, spatial_dimension, spatial_dimension, false, _ek_not_defined);
}
/* -------------------------------------------------------------------------- */
void Mesh::getGlobalConnectivity(ElementTypeMapArray<UInt> & global_connectivity,
UInt dimension,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = firstType(dimension, ghost_type);
Mesh::type_iterator end = lastType(dimension, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
Array<UInt> & local_conn = connectivities(type, ghost_type);
Array<UInt> & g_connectivity = global_connectivity(type, ghost_type);
if (!nodes_global_ids)
nodes_global_ids = mesh_parent->nodes_global_ids;
UInt * local_c = local_conn.storage();
UInt * global_c = g_connectivity.storage();
UInt nb_terms = local_conn.getSize() * local_conn.getNbComponent();
for (UInt i = 0; i < nb_terms; ++i, ++local_c, ++global_c)
*global_c = (*nodes_global_ids)(*local_c);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Mesh::getGroupDumper(const std::string & dumper_name,
const std::string & group_name){
if (group_name == "all") return this->getDumper(dumper_name);
else return element_groups[group_name]->getDumper(dumper_name);
}
/* -------------------------------------------------------------------------- */
#define AKANTU_INSTANTIATE_INIT(type) \
template void Mesh::initElementTypeMapArray<type>(ElementTypeMapArray<type> & vect, \
UInt nb_component, \
UInt dim, \
const bool & flag_nb_elem_multiply, \
ElementKind element_kind, \
bool size_to_nb_element) const; \
template void Mesh::initElementTypeMapArray<type>(ElementTypeMapArray<type> & vect, \
UInt nb_component, \
UInt dim, \
GhostType gt, \
const bool & flag_nb_elem_multiply, \
ElementKind element_kind, \
bool size_to_nb_element) const; \
template void Mesh::initElementTypeMapArray<type>(ElementTypeMapArray<type> & vect, \
UInt nb_component, \
UInt dim, \
GhostType gt, \
const type & default_value, \
const bool & flag_nb_elem_multiply, \
ElementKind element_kind, \
bool size_to_nb_element) const;
AKANTU_INSTANTIATE_INIT(Real);
AKANTU_INSTANTIATE_INIT(UInt);
AKANTU_INSTANTIATE_INIT(Int);
AKANTU_INSTANTIATE_INIT(bool);
/* -------------------------------------------------------------------------- */
template <typename T>
ElementTypeMap<UInt> Mesh::getNbDataPerElem(ElementTypeMapArray<T> & array,
const ElementKind & element_kind){
ElementTypeMap<UInt> nb_data_per_elem;
typename ElementTypeMapArray<T>::type_iterator it =
array.firstType(spatial_dimension, _not_ghost,element_kind);
typename ElementTypeMapArray<T>::type_iterator last_type =
array.lastType(spatial_dimension, _not_ghost,element_kind);
for(; it != last_type; ++it) {
UInt nb_elements = this->getNbElement(*it);
nb_data_per_elem(*it) =
array(*it).getNbComponent() *
array(*it).getSize();
nb_data_per_elem(*it) /= nb_elements;
}
return nb_data_per_elem;
}
/* -------------------------------------------------------------------------- */
template
ElementTypeMap<UInt> Mesh::getNbDataPerElem(ElementTypeMapArray<Real> & array,
const ElementKind & element_kind);
template
ElementTypeMap<UInt> Mesh::getNbDataPerElem(ElementTypeMapArray<UInt> & array,
const ElementKind & element_kind);
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
template <typename T>
dumper::Field * Mesh::createFieldFromAttachedData(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind){
dumper::Field * field = NULL;
ElementTypeMapArray<T> * internal = NULL;
try {
internal = &(this->getData<T>(field_id));
}
catch (...){
return NULL;
}
ElementTypeMap<UInt> nb_data_per_elem =
this->getNbDataPerElem(*internal,element_kind);
field =
this->createElementalField<T, dumper::InternalMaterialField>(*internal,
group_name,
this->spatial_dimension,
element_kind,
nb_data_per_elem);
return field;
}
template dumper::Field *
Mesh::createFieldFromAttachedData<Real>(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind);
template dumper::Field *
Mesh::createFieldFromAttachedData<UInt>(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind);
#endif
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/mesh/mesh.hh b/src/mesh/mesh.hh
index 1e165d4ce..4b7d02ab6 100644
--- a/src/mesh/mesh.hh
+++ b/src/mesh/mesh.hh
@@ -1,574 +1,575 @@
/**
* @file mesh.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Thu Jan 14 2016
*
* @brief the class representing the meshes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_HH__
#define __AKANTU_MESH_HH__
/* -------------------------------------------------------------------------- */
#include "aka_config.hh"
#include "aka_common.hh"
#include "aka_memory.hh"
#include "aka_array.hh"
#include "element_class.hh"
#include "element_type_map.hh"
#include "aka_event_handler_manager.hh"
#include "group_manager.hh"
#include "element.hh"
/* -------------------------------------------------------------------------- */
#include <set>
/* -------------------------------------------------------------------------- */
#include "mesh_data.hh"
#include "dumpable.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Mesh modifications events */
/* -------------------------------------------------------------------------- */
#include "mesh_events.hh"
/* -------------------------------------------------------------------------- */
/* Mesh */
/* -------------------------------------------------------------------------- */
/**
* @class Mesh this contain the coordinates of the nodes in the Mesh.nodes
* Array, and the connectivity. The connectivity are stored in by element
* types.
*
* To know all the element types present in a mesh you can get the
* Mesh::ConnectivityTypeList
*
* In order to loop on all element you have to loop on all types like this :
* @code{.cpp}
Mesh::type_iterator it = mesh.firstType(dim, ghost_type);
Mesh::type_iterator end = mesh.lastType(dim, ghost_type);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it);
const Array<UInt> & conn = mesh.getConnectivity(*it);
for(UInt e = 0; e < nb_element; ++e) {
...
}
}
@endcode
*/
class Mesh : protected Memory,
public EventHandlerManager<MeshEventHandler>,
public GroupManager,
public Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
/// constructor that create nodes coordinates array
Mesh(UInt spatial_dimension,
const ID & id = "mesh",
const MemoryID & memory_id = 0);
/// constructor that use an existing nodes coordinates array, by knowing its ID
Mesh(UInt spatial_dimension,
const ID & nodes_id,
const ID & id,
const MemoryID & memory_id = 0);
/**
* constructor that use an existing nodes coordinates
* array, by getting the vector of coordinates
*/
Mesh(UInt spatial_dimension,
Array<Real> & nodes,
const ID & id = "mesh",
const MemoryID & memory_id = 0);
virtual ~Mesh();
/// @typedef ConnectivityTypeList list of the types present in a Mesh
typedef std::set<ElementType> ConnectivityTypeList;
/// read the mesh from a file
void read (const std::string & filename, const MeshIOType & mesh_io_type = _miot_auto);
/// write the mesh to a file
void write(const std::string & filename, const MeshIOType & mesh_io_type = _miot_auto);
private:
/// initialize the connectivity to NULL and other stuff
void init();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/// function that computes the bounding box (fills xmin, xmax)
void computeBoundingBox();
#ifdef AKANTU_CORE_CXX11
/// translate the mesh by the given amount in x[, y[, z]] directions
template <typename... Args> void translate(Args... params);
#endif
/// init a by-element-type real vector with provided ids
template<typename T>
void initElementTypeMapArray(ElementTypeMapArray<T> & v,
UInt nb_component,
UInt spatial_dimension,
const bool & flag_nb_node_per_elem_multiply = false,
ElementKind element_kind = _ek_regular,
bool size_to_nb_element = false) const; /// @todo: think about nicer way to do it
template<typename T>
void initElementTypeMapArray(ElementTypeMapArray<T> & v,
UInt nb_component,
UInt spatial_dimension,
GhostType ghost_type,
const bool & flag_nb_node_per_elem_multiply = false,
ElementKind element_kind = _ek_regular,
bool size_to_nb_element = false) const; /// @todo: think about nicer way to do it
template<typename T>
void initElementTypeMapArray(ElementTypeMapArray<T> & v,
UInt nb_component,
UInt spatial_dimension,
GhostType ghost_type,
const T & default_value,
const bool & flag_nb_node_per_elem_multiply = false,
ElementKind element_kind = _ek_regular,
bool size_to_nb_element = false) const; /// @todo: think about nicer way to do it
/// extract coordinates of nodes from an element
template<typename T>
inline void extractNodalValuesFromElement(const Array<T> & nodal_values,
T * elemental_values,
UInt * connectivity,
UInt n_nodes,
UInt nb_degree_of_freedom) const;
// /// extract coordinates of nodes from a reversed element
// inline void extractNodalCoordinatesFromPBCElement(Real * local_coords,
// UInt * connectivity,
// UInt n_nodes);
/// convert a element to a linearized element
inline UInt elementToLinearized(const Element & elem) const;
/// convert a linearized element to an element
inline Element linearizedToElement (UInt linearized_element) const;
/// update the types offsets array for the conversions
inline void updateTypesOffsets(const GhostType & ghost_type);
/// add a Array of connectivity for the type <type>.
inline void addConnectivityType(const ElementType & type,
const GhostType & ghost_type = _not_ghost);
/* ------------------------------------------------------------------------ */
template <class Event>
inline void sendEvent(Event & event) {
// if(event.getList().getSize() != 0)
EventHandlerManager<MeshEventHandler>::sendEvent<Event>(event);
}
/* ------------------------------------------------------------------------ */
template<typename T>
inline void removeNodesFromArray(Array<T> & vect, const Array<UInt> & new_numbering);
/// initialize normals
void initNormals();
/// init facets' mesh
Mesh & initMeshFacets(const ID & id = "mesh_facets");
/// define parent mesh
void defineMeshParent(const Mesh & mesh);
/// get global connectivity array
void getGlobalConnectivity(ElementTypeMapArray<UInt> & global_connectivity,
UInt dimension,
GhostType ghost_type);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the id of the mesh
AKANTU_GET_MACRO(ID, Memory::id, const ID &);
/// get the spatial dimension of the mesh = number of component of the coordinates
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// get the nodes Array aka coordinates
AKANTU_GET_MACRO(Nodes, *nodes, const Array<Real> &);
AKANTU_GET_MACRO_NOT_CONST(Nodes, *nodes, Array<Real> &);
/// get the normals for the elements
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Normals, normals, Real);
/// get the number of nodes
AKANTU_GET_MACRO(NbNodes, nodes->getSize(), UInt);
/// get the Array of global ids of the nodes (only used in parallel)
AKANTU_GET_MACRO(GlobalNodesIds, *nodes_global_ids, const Array<UInt> &);
AKANTU_GET_MACRO_NOT_CONST(GlobalNodesIds, *nodes_global_ids, Array<UInt> &);
/// get the global id of a node
inline UInt getNodeGlobalId(UInt local_id) const;
/// get the global number of nodes
inline UInt getNbGlobalNodes() const;
/// get the nodes type Array
AKANTU_GET_MACRO(NodesType, nodes_type, const Array<Int> &);
protected:
AKANTU_GET_MACRO_NOT_CONST(NodesType, nodes_type, Array<Int> &);
public:
inline Int getNodeType(UInt local_id) const;
/// say if a node is a pure ghost node
inline bool isPureGhostNode(UInt n) const;
/// say if a node is pur local or master node
inline bool isLocalOrMasterNode(UInt n) const;
inline bool isLocalNode(UInt n) const;
inline bool isMasterNode(UInt n) const;
inline bool isSlaveNode(UInt n) const;
AKANTU_GET_MACRO(LowerBounds, lower_bounds, const Vector<Real> &);
AKANTU_GET_MACRO(UpperBounds, upper_bounds, const Vector<Real> &);
AKANTU_GET_MACRO(LocalLowerBounds, local_lower_bounds, const Vector<Real> &);
AKANTU_GET_MACRO(LocalUpperBounds, local_upper_bounds, const Vector<Real> &);
/// get the connectivity Array for a given type
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Connectivity, connectivities, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Connectivity, connectivities, UInt);
AKANTU_GET_MACRO(Connectivities, connectivities, const ElementTypeMapArray<UInt> &);
/// get the number of element of a type in the mesh
inline UInt getNbElement(const ElementType & type, const GhostType & ghost_type = _not_ghost) const;
/// get the number of element for a given ghost_type and a given dimension
inline UInt getNbElement(const UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & kind = _ek_not_defined) const;
/// get the connectivity list either for the elements or the ghost elements
inline const ConnectivityTypeList & getConnectivityTypeList(const GhostType & ghost_type = _not_ghost) const;
/// compute the barycenter of a given element
inline void getBarycenter(UInt element, const ElementType & type, Real * barycenter,
GhostType ghost_type = _not_ghost) const;
inline void getBarycenter(const Element & element, Vector<Real> & barycenter) const;
/// get the element connected to a subelement
const Array< std::vector<Element> > & getElementToSubelement(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/// get the element connected to a subelement
Array< std::vector<Element> > & getElementToSubelement(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost);
/// get the subelement connected to an element
const Array<Element> & getSubelementToElement(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/// get the subelement connected to an element
Array<Element> & getSubelementToElement(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost);
/// get a name field associated to the mesh
template<typename T>
inline const Array<T> & getData(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/// get a name field associated to the mesh
template<typename T>
inline Array<T> & getData(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type = _not_ghost);
/// register a new ElementalTypeMap in the MeshData
template<typename T>
inline ElementTypeMapArray<T> & registerData(const std::string & data_name);
/// get a name field associated to the mesh
template<typename T>
inline const ElementTypeMapArray<T> & getData(const std::string & data_name) const;
/// get a name field associated to the mesh
template<typename T>
inline ElementTypeMapArray<T> & getData(const std::string & data_name);
template <typename T>
ElementTypeMap<UInt> getNbDataPerElem(ElementTypeMapArray<T> & array,
const ElementKind & element_kind);
template <typename T>
dumper::Field * createFieldFromAttachedData(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind);
/// templated getter returning the pointer to data in MeshData (modifiable)
template<typename T>
inline Array<T> * getDataPointer(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type = _not_ghost,
UInt nb_component = 1,
bool size_to_nb_element = true,
bool resize_with_parent = false);
/// Facets mesh accessor
AKANTU_GET_MACRO(MeshFacets, *mesh_facets, const Mesh &);
AKANTU_GET_MACRO_NOT_CONST(MeshFacets, *mesh_facets, Mesh &);
/// Parent mesh accessor
AKANTU_GET_MACRO(MeshParent, *mesh_parent, const Mesh &);
inline bool isMeshFacets() const { return this->is_mesh_facets; }
/// defines is the mesh is distributed or not
inline bool isDistributed() const { return this->is_distributed; }
#ifndef SWIG
/// return the dumper from a group and and a dumper name
DumperIOHelper & getGroupDumper(const std::string & dumper_name,
const std::string & group_name);
#endif
/* ------------------------------------------------------------------------ */
/* Wrappers on ElementClass functions */
/* ------------------------------------------------------------------------ */
public:
/// get the number of nodes per element for a given element type
static inline UInt getNbNodesPerElement(const ElementType & type);
/// get the number of nodes per element for a given element type considered as
/// a first order element
static inline ElementType getP1ElementType(const ElementType & type);
/// get the kind of the element type
static inline ElementKind getKind(const ElementType & type);
/// get spatial dimension of a type of element
static inline UInt getSpatialDimension(const ElementType & type);
/// get number of facets of a given element type
static inline UInt getNbFacetsPerElement(const ElementType & type);
/// get number of facets of a given element type
static inline UInt getNbFacetsPerElement(const ElementType & type, UInt t);
/// get local connectivity of a facet for a given facet type
static inline MatrixProxy<UInt> getFacetLocalConnectivity(const ElementType & type, UInt t = 0);
/// get connectivity of facets for a given element
inline Matrix<UInt> getFacetConnectivity(const Element & element, UInt t = 0) const;
/// get the number of type of the surface element associated to a given element type
static inline UInt getNbFacetTypes(const ElementType & type, UInt t = 0);
/// get the type of the surface element associated to a given element
static inline ElementType getFacetType(const ElementType & type, UInt t = 0);
/// get all the type of the surface element associated to a given element
static inline VectorProxy<ElementType> getAllFacetTypes(const ElementType & type);
/// get the number of nodes in the given element list
static inline UInt getNbNodesPerElementList(const Array<Element> & elements);
/* ------------------------------------------------------------------------ */
/* Element type Iterator */
/* ------------------------------------------------------------------------ */
typedef ElementTypeMapArray<UInt, ElementType>::type_iterator type_iterator;
inline type_iterator firstType(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_regular) const {
return connectivities.firstType(dim, ghost_type, kind);
}
inline type_iterator lastType(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_regular) const {
return connectivities.lastType(dim, ghost_type, kind);
}
/* ------------------------------------------------------------------------ */
/* Private methods for friends */
/* ------------------------------------------------------------------------ */
private:
friend class MeshAccessor;
friend class MeshIOMSH;
friend class MeshIOMSHStruct;
friend class MeshIODiana;
friend class MeshUtils;
friend class DistributedSynchronizer;
template<class T> friend class SpatialGrid;
#if defined(AKANTU_COHESIVE_ELEMENT)
friend class CohesiveElementInserter;
#endif
#if defined(AKANTU_IGFEM)
template<UInt dim> friend class MeshIgfemSphericalGrowingGel;
#endif
AKANTU_GET_MACRO(NodesPointer, nodes, Array<Real> *);
/// get a pointer to the nodes_global_ids Array<UInt> and create it if necessary
inline Array<UInt> * getNodesGlobalIdsPointer();
/// get a pointer to the nodes_type Array<Int> and create it if necessary
inline Array<Int> * getNodesTypePointer();
/// get a pointer to the connectivity Array for the given type and create it if necessary
inline Array<UInt> * getConnectivityPointer(const ElementType & type,
const GhostType & ghost_type = _not_ghost);
/// get a pointer to the element_to_subelement Array for the given type and create it if necessary
inline Array< std::vector<Element> > * getElementToSubelementPointer(const ElementType & type,
const GhostType & ghost_type = _not_ghost);
/// get a pointer to the subelement_to_element Array for the given type and create it if necessary
inline Array<Element > * getSubelementToElementPointer(const ElementType & type,
const GhostType & ghost_type = _not_ghost);
AKANTU_GET_MACRO_NOT_CONST(MeshData, mesh_data, MeshData &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// array of the nodes coordinates
Array<Real> * nodes;
/// global node ids
Array<UInt> * nodes_global_ids;
/// node type, -3 pure ghost, -2 master for the node, -1 normal node, i in
/// [0-N] slave node and master is proc i
Array<Int> nodes_type;
/// global number of nodes;
UInt nb_global_nodes;
/// boolean to know if the nodes have to be deleted with the mesh or not
bool created_nodes;
/// all class of elements present in this mesh (for heterogenous meshes)
ElementTypeMapArray<UInt> connectivities;
/// map to normals for all class of elements present in this mesh
ElementTypeMapArray<Real> normals;
/// list of all existing types in the mesh
ConnectivityTypeList type_set;
/// the spatial dimension of this mesh
UInt spatial_dimension;
/// types offsets
Array<UInt> types_offsets;
/// list of all existing types in the mesh
ConnectivityTypeList ghost_type_set;
/// ghost types offsets
Array<UInt> ghost_types_offsets;
/// min of coordinates
Vector<Real> lower_bounds;
/// max of coordinates
Vector<Real> upper_bounds;
/// size covered by the mesh on each direction
Vector<Real> size;
/// local min of coordinates
Vector<Real> local_lower_bounds;
/// local max of coordinates
Vector<Real> local_upper_bounds;
/// Extra data loaded from the mesh file
MeshData mesh_data;
/// facets' mesh
Mesh * mesh_facets;
/// parent mesh (this is set for mesh_facets meshes)
const Mesh * mesh_parent;
/// defines if current mesh is mesh_facets or not
bool is_mesh_facets;
/// defines if the mesh is centralized or distributed
bool is_distributed;
};
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const Element & _this)
{
_this.printself(stream);
return stream;
}
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const Mesh & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* Inline functions */
/* -------------------------------------------------------------------------- */
#include "mesh_inline_impl.cc"
#include "element_type_map_tmpl.hh"
//#include "group_manager_inline_impl.cc"
//#include "element_group_inline_impl.cc"
#endif /* __AKANTU_MESH_HH__ */
diff --git a/src/mesh/mesh_accessor.hh b/src/mesh/mesh_accessor.hh
index f820383aa..95126bd52 100644
--- a/src/mesh/mesh_accessor.hh
+++ b/src/mesh/mesh_accessor.hh
@@ -1,108 +1,107 @@
/**
* @file mesh_accessor.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Tue Jun 30 2015
*
- * @brief this class allow to access some private member of mesh it is used for
+ * @brief this class allow to access some private member of mesh it is used for
* IO for examples
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_MESH_ACCESSOR_HH__
#define __AKANTU_MESH_ACCESSOR_HH__
__BEGIN_AKANTU__
class MeshAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshAccessor() {};
virtual ~MeshAccessor() {};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the global number of nodes
inline UInt getNbGlobalNodes(const Mesh & mesh) const { return mesh.nb_global_nodes; };
/// set the global number of nodes
inline void setNbGlobalNodes(Mesh & mesh, UInt nb_global_nodes) const
{ mesh.nb_global_nodes = nb_global_nodes; };
/// get a pointer to the nodes_global_ids Array<UInt> and create it if necessary
inline Array<UInt> & getNodesGlobalIds(Mesh & mesh) {
return *(mesh.getNodesGlobalIdsPointer());
}
/// get a pointer to the nodes_type Array<Int> and create it if necessary
inline Array<Int> & getNodesType(Mesh & mesh) {
return *(mesh.getNodesTypePointer());
}
/// get a pointer to the connectivity Array for the given type and create it if necessary
inline Array<UInt> & getConnectivity(Mesh & mesh,
const ElementType & type,
const GhostType & ghost_type = _not_ghost) {
return *(mesh.getConnectivityPointer(type, ghost_type));
}
/// get a pointer to the element_to_subelement Array for the given type and create it if necessary
inline Array< std::vector<Element> > & getElementToSubelement(Mesh & mesh,
const ElementType & type,
const GhostType & ghost_type = _not_ghost) {
return *(mesh.getElementToSubelementPointer(type, ghost_type));
}
/// get a pointer to the subelement_to_element Array for the given type and create it if necessary
inline Array<Element > & getSubelementToElement(Mesh & mesh,
const ElementType & type,
const GhostType & ghost_type = _not_ghost) {
return *(mesh.getSubelementToElementPointer(type, ghost_type));
}
template<typename T>
inline Array<T> & getData(Mesh & mesh,
const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type = _not_ghost,
UInt nb_component = 1,
bool size_to_nb_element = true,
bool resize_with_parent = false) {
return *(mesh.getDataPointer<T>(data_name,
el_type,
ghost_type,
nb_component,
size_to_nb_element,
resize_with_parent));
}
};
__END_AKANTU__
#endif /* __AKANTU_MESH_ACCESSOR_HH__ */
diff --git a/src/mesh/mesh_data.cc b/src/mesh/mesh_data.cc
index 92efc1739..6c49bc088 100644
--- a/src/mesh/mesh_data.cc
+++ b/src/mesh/mesh_data.cc
@@ -1,48 +1,49 @@
/**
* @file mesh_data.cc
*
* @author Dana Christen <dana.christen@gmail.com>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief Stores generic data loaded from the mesh file
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "mesh.hh"
#include "mesh_data.hh"
__BEGIN_AKANTU__
MeshData::MeshData(const ID & _id, const ID & parent_id, const MemoryID & mem_id)
: Memory(parent_id + ":" + _id, mem_id) {
}
MeshData::~MeshData() {
ElementalDataMap::iterator it, end;
for(it = elemental_data.begin(); it != elemental_data.end(); ++it) {
delete it->second;
}
}
__END_AKANTU__
diff --git a/src/mesh/mesh_data.hh b/src/mesh/mesh_data.hh
index 6d7e4dd6a..c9b515eed 100644
--- a/src/mesh/mesh_data.hh
+++ b/src/mesh/mesh_data.hh
@@ -1,145 +1,145 @@
/**
* @file mesh_data.hh
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 03 2013
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Thu Nov 05 2015
*
* @brief Stores generic data loaded from the mesh file
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_DATA_HH__
#define __AKANTU_MESH_DATA_HH__
/* -------------------------------------------------------------------------- */
#include "element_type_map.hh"
#include "aka_memory.hh"
#include <map>
#include <string>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
#define AKANTU_MESH_DATA_TYPES \
((_tc_int, Int)) \
((_tc_uint, UInt)) \
((_tc_real, Real)) \
((_tc_element, Element)) \
((_tc_std_string, std::string)) \
((_tc_std_vector_element, std::vector<Element>)) \
#define AKANTU_MESH_DATA_TUPLE_FIRST_ELEM(s, data, elem) BOOST_PP_TUPLE_ELEM(2, 0, elem)
enum MeshDataTypeCode {
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_MESH_DATA_TUPLE_FIRST_ELEM, , AKANTU_MESH_DATA_TYPES)),
_tc_unknown
};
class MeshData : public Memory {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
private:
typedef MeshDataTypeCode TypeCode;
typedef std::map<std::string, ElementTypeMapBase *> ElementalDataMap;
typedef std::vector<std::string> StringVector;
typedef std::map<std::string, TypeCode> TypeCodeMap;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshData(const ID & id = "mesh_data", const ID & parent_id = "", const MemoryID & memory_id = 0);
~MeshData();
/* ------------------------------------------------------------------------ */
/* Methods and accessors */
/* ------------------------------------------------------------------------ */
public:
/// Register new elemental data (and alloc data) with check if the name is new
template<typename T>
void registerElementalData(const std::string & name);
inline void registerElementalData(const std::string & name, TypeCode type);
/// Get an existing elemental data array
template<typename T>
const Array<T> & getElementalDataArray(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
template<typename T>
Array<T> & getElementalDataArray(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type = _not_ghost);
/// Get an elemental data array, if it does not exist: allocate it
template<typename T>
Array<T> & getElementalDataArrayAlloc(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type = _not_ghost,
UInt nb_component = 1);
/// get the names of the data stored in elemental_data
inline void getTagNames(StringVector & tags, const ElementType & type, const GhostType & ghost_type = _not_ghost) const;
/// get the type of the data stored in elemental_data
template<typename T>
TypeCode getTypeCode() const;
inline TypeCode getTypeCode(const std::string name) const;
template<typename T>
inline UInt getNbComponentTemplated(const std::string, const ElementType & el_type, const GhostType & ghost_type) const;
inline UInt getNbComponent(const std::string name, const ElementType & el_type, const GhostType & ghost_type = _not_ghost) const;
/// Get an existing elemental data
template<typename T>
const ElementTypeMapArray<T> & getElementalData(const std::string & name) const;
template<typename T>
ElementTypeMapArray<T> & getElementalData(const std::string & name);
private:
/// Register new elemental data (add alloc data)
template<typename T>
ElementTypeMapArray<T> * allocElementalData(const std::string & name);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// Map when elemental data is stored as ElementTypeMap
ElementalDataMap elemental_data;
/// Map when elementalType of the data stored in elemental_data
TypeCodeMap typecode_map;
};
#include "mesh_data_tmpl.hh"
#undef AKANTU_MESH_DATA_TUPLE_FIRST_ELEM
__END_AKANTU__
#endif /* __AKANTU_MESH_DATA_HH__ */
diff --git a/src/mesh/mesh_data_tmpl.hh b/src/mesh/mesh_data_tmpl.hh
index 852fa8798..27343db0f 100644
--- a/src/mesh/mesh_data_tmpl.hh
+++ b/src/mesh/mesh_data_tmpl.hh
@@ -1,218 +1,218 @@
/**
* @file mesh_data_tmpl.hh
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 03 2013
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Thu Nov 05 2015
*
* @brief Stores generic data loaded from the mesh file
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
__END_AKANTU__
#include <iostream>
#define MESH_DATA_GET_TYPE(r, data, type) \
template<> \
inline MeshDataTypeCode MeshData::getTypeCode<BOOST_PP_TUPLE_ELEM(2, 1, type)>() const { \
return BOOST_PP_TUPLE_ELEM(2, 0, type); \
}
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
// get the type of the data stored in elemental_data
template<typename T>
inline MeshDataTypeCode MeshData::getTypeCode() const {
AKANTU_DEBUG_ERROR("Type " << debug::demangle(typeid(T).name()) << "not implemented by MeshData.");
}
/* -------------------------------------------------------------------------- */
BOOST_PP_SEQ_FOR_EACH(MESH_DATA_GET_TYPE, void, AKANTU_MESH_DATA_TYPES)
#undef MESH_DATA_GET_TYPE
inline MeshDataTypeCode MeshData::getTypeCode(const std::string name) const {
TypeCodeMap::const_iterator it = typecode_map.find(name);
if(it == typecode_map.end()) AKANTU_EXCEPTION("No dataset named " << name << " found.");
return it->second;
}
/* -------------------------------------------------------------------------- */
// Register new elemental data templated (and alloc data) with check if the name is new
template<typename T>
void MeshData::registerElementalData(const std::string & name) {
ElementalDataMap::iterator it = elemental_data.find(name);
if(it == elemental_data.end()) {
allocElementalData<T>(name);
} else{
AKANTU_DEBUG_INFO("Data named " << name << " already registered.");
}
}
/* -------------------------------------------------------------------------- */
// Register new elemental data of a given MeshDataTypeCode with check if the name is new
#define AKANTU_MESH_DATA_CASE_MACRO(r, name, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem) : { registerElementalData<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(name); break; }
inline void MeshData::registerElementalData(const std::string & name, MeshDataTypeCode type) {
switch(type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_MESH_DATA_CASE_MACRO, name, AKANTU_MESH_DATA_TYPES)
default : AKANTU_DEBUG_ERROR("Type " << type << "not implemented by MeshData.");
}
}
#undef AKANTU_MESH_DATA_CASE_MACRO
/* -------------------------------------------------------------------------- */
/// Register new elemental data (and alloc data)
template<typename T>
ElementTypeMapArray<T> * MeshData::allocElementalData(const std::string & name) {
ElementTypeMapArray<T> * dataset = new ElementTypeMapArray<T>(name, id, memory_id);
elemental_data[name] = dataset;
typecode_map[name] = getTypeCode<T>();
return dataset;
}
/* -------------------------------------------------------------------------- */
template<typename T>
const ElementTypeMapArray<T> & MeshData::getElementalData(const std::string & name) const {
ElementalDataMap::const_iterator it = elemental_data.find(name);
if(it == elemental_data.end()) AKANTU_EXCEPTION("No dataset named " << name << " found.");
return dynamic_cast<const ElementTypeMapArray<T> &>(*(it->second));
}
/* -------------------------------------------------------------------------- */
// Get an existing elemental data
template<typename T>
ElementTypeMapArray<T> & MeshData::getElementalData(const std::string & name) {
ElementalDataMap::iterator it = elemental_data.find(name);
if(it == elemental_data.end()) AKANTU_EXCEPTION("No dataset named " << name << " found.");
return dynamic_cast<ElementTypeMapArray<T> &>(*(it->second));
}
/* -------------------------------------------------------------------------- */
// Get an existing elemental data array for an element type
template<typename T>
const Array<T> & MeshData::getElementalDataArray(const std::string & name,
const ElementType & elem_type,
const GhostType & ghost_type) const {
ElementalDataMap::const_iterator it = elemental_data.find(name);
if(it == elemental_data.end()) {
AKANTU_EXCEPTION("Data named " << name << " not registered for type: " << elem_type << " - ghost_type:" << ghost_type << "!");
}
return dynamic_cast<const ElementTypeMapArray<T> &>(*(it->second))(elem_type, ghost_type);
}
template<typename T>
Array<T> & MeshData::getElementalDataArray(const std::string & name,
const ElementType & elem_type,
const GhostType & ghost_type) {
ElementalDataMap::iterator it = elemental_data.find(name);
if(it == elemental_data.end()) {
AKANTU_EXCEPTION("Data named " << name << " not registered for type: " << elem_type << " - ghost_type:" << ghost_type << "!");
}
return dynamic_cast<ElementTypeMapArray<T> &>(*(it->second))(elem_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
// Get an elemental data array, if it does not exist: allocate it
template<typename T>
Array<T> & MeshData::getElementalDataArrayAlloc(const std::string & name,
const ElementType & elem_type,
const GhostType & ghost_type,
UInt nb_component) {
ElementalDataMap::iterator it = elemental_data.find(name);
ElementTypeMapArray<T> * dataset;
if(it == elemental_data.end()) {
dataset = allocElementalData<T>(name);
} else {
dataset = dynamic_cast<ElementTypeMapArray<T> *>(it->second);
}
AKANTU_DEBUG_ASSERT(getTypeCode<T>() == typecode_map.find(name)->second, "Function getElementalDataArrayAlloc called with the wrong type!");
if(!(dataset->exists(elem_type, ghost_type))) {
dataset->alloc(0, nb_component, elem_type, ghost_type);
}
return (*dataset)(elem_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
#define AKANTU_MESH_DATA_CASE_MACRO(r, name, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem) : { \
nb_comp = getNbComponentTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(name, el_type, ghost_type); \
break; \
} \
inline UInt MeshData::getNbComponent(const std::string name, const ElementType & el_type, const GhostType & ghost_type) const {
TypeCodeMap::const_iterator it = typecode_map.find(name);
UInt nb_comp(0);
if(it == typecode_map.end()) {
AKANTU_EXCEPTION("Could not determine the type held in dataset " << name << " for type: " << el_type << " - ghost_type:" << ghost_type << ".");
}
MeshDataTypeCode type = it->second;
switch(type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_MESH_DATA_CASE_MACRO, name, AKANTU_MESH_DATA_TYPES)
default : AKANTU_DEBUG_ERROR("Could not call the correct instance of getNbComponentTemplated."); break;
}
return nb_comp;
}
#undef AKANTU_MESH_DATA_CASE_MACRO
/* -------------------------------------------------------------------------- */
template<typename T>
inline UInt MeshData::getNbComponentTemplated(const std::string name, const ElementType & el_type, const GhostType & ghost_type) const {
return getElementalDataArray<T>(name, el_type, ghost_type).getNbComponent();
}
/* -------------------------------------------------------------------------- */
// get the names of the data stored in elemental_data
#define AKANTU_MESH_DATA_CASE_MACRO(r, name, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem) : { \
ElementTypeMapArray<BOOST_PP_TUPLE_ELEM(2, 1, elem)> * dataset; \
dataset = dynamic_cast< ElementTypeMapArray<BOOST_PP_TUPLE_ELEM(2, 1, elem)> * >(it->second); \
exists = dataset->exists(el_type, ghost_type); \
break; \
} \
inline void MeshData::getTagNames(StringVector & tags, const ElementType & el_type, const GhostType & ghost_type) const {
tags.clear();
bool exists(false);
ElementalDataMap::const_iterator it = elemental_data.begin();
ElementalDataMap::const_iterator it_end = elemental_data.end();
for(; it != it_end; ++it) {
MeshDataTypeCode type = getTypeCode(it->first);
switch(type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_MESH_DATA_CASE_MACRO, , AKANTU_MESH_DATA_TYPES)
default : AKANTU_DEBUG_ERROR("Could not determine the proper type to (dynamic-)cast."); break;
}
if(exists) {
tags.push_back(it->first);
}
}
}
#undef AKANTU_MESH_DATA_CASE_MACRO
/* -------------------------------------------------------------------------- */
diff --git a/src/mesh/mesh_events.hh b/src/mesh/mesh_events.hh
index bd1acd14e..b3d7036f1 100644
--- a/src/mesh/mesh_events.hh
+++ b/src/mesh/mesh_events.hh
@@ -1,179 +1,180 @@
/**
* @file mesh_events.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date Fri Feb 20 10:48:36 2015
+ * @date creation: Fri Feb 20 2015
+ * @date last modification: Mon Dec 07 2015
*
* @brief Classes corresponding to mesh events type
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_EVENTS_HH__
#define __AKANTU_MESH_EVENTS_HH__
/// akantu::MeshEvent is the base event for meshes
template <class Entity> class MeshEvent {
public:
virtual ~MeshEvent() {}
/// Get the list of entity modified by the event nodes or elements
const Array<Entity> & getList() const { return list; }
/// Get the list of entity modified by the event nodes or elements
Array<Entity> & getList() { return list; }
protected:
Array<Entity> list;
};
class Mesh;
/// akantu::MeshEvent related to new nodes in the mesh
class NewNodesEvent : public MeshEvent<UInt> {
public:
virtual ~NewNodesEvent(){};
};
/// akantu::MeshEvent related to nodes removed from the mesh
class RemovedNodesEvent : public MeshEvent<UInt> {
public:
virtual ~RemovedNodesEvent(){};
inline RemovedNodesEvent(const Mesh & mesh);
/// Get the new numbering following suppression of nodes from nodes arrays
AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, Array<UInt> &);
/// Get the new numbering following suppression of nodes from nodes arrays
AKANTU_GET_MACRO(NewNumbering, new_numbering, const Array<UInt> &);
private:
Array<UInt> new_numbering;
};
/// akantu::MeshEvent related to new elements in the mesh
class NewElementsEvent : public MeshEvent<Element> {
public:
virtual ~NewElementsEvent(){};
};
/// akantu::MeshEvent related to elements removed from the mesh
class RemovedElementsEvent : public MeshEvent<Element> {
public:
virtual ~RemovedElementsEvent(){};
inline RemovedElementsEvent(const Mesh & mesh,
ID new_numbering_id = "new_numbering");
/// Get the new numbering following suppression of elements from elements
/// arrays
AKANTU_GET_MACRO(NewNumbering, new_numbering,
const ElementTypeMapArray<UInt> &);
/// Get the new numbering following suppression of elements from elements
/// arrays
AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering,
ElementTypeMapArray<UInt> &);
/// Get the new numbering following suppression of elements from elements
/// arrays
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(NewNumbering, new_numbering, UInt);
/// Get the new numbering following suppression of elements from elements
/// arrays
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NewNumbering, new_numbering, UInt);
protected:
ElementTypeMapArray<UInt> new_numbering;
};
/// akantu::MeshEvent for element that changed in some sort, can be seen as a
/// combination of removed and added elements
class ChangedElementsEvent : public RemovedElementsEvent {
public:
virtual ~ChangedElementsEvent(){};
inline ChangedElementsEvent(
const Mesh & mesh, ID new_numbering_id = "changed_event:new_numbering")
: RemovedElementsEvent(mesh, new_numbering_id){};
AKANTU_GET_MACRO(ListOld, list, const Array<Element> &);
AKANTU_GET_MACRO_NOT_CONST(ListOld, list, Array<Element> &);
AKANTU_GET_MACRO(ListNew, new_list, const Array<Element> &);
AKANTU_GET_MACRO_NOT_CONST(ListNew, new_list, Array<Element> &);
protected:
Array<Element> new_list;
};
/* -------------------------------------------------------------------------- */
class MeshEventHandler {
public:
virtual ~MeshEventHandler(){};
/* ------------------------------------------------------------------------ */
/* Internal code */
/* ------------------------------------------------------------------------ */
private:
/// send a akantu::NewNodesEvent
inline void sendEvent(const NewNodesEvent & event) {
onNodesAdded(event.getList(), event);
}
/// send a akantu::RemovedNodesEvent
inline void sendEvent(const RemovedNodesEvent & event) {
onNodesRemoved(event.getList(), event.getNewNumbering(), event);
}
/// send a akantu::NewElementsEvent
inline void sendEvent(const NewElementsEvent & event) {
onElementsAdded(event.getList(), event);
}
/// send a akantu::RemovedElementsEvent
inline void sendEvent(const RemovedElementsEvent & event) {
onElementsRemoved(event.getList(), event.getNewNumbering(), event);
}
/// send a akantu::ChangedElementsEvent
inline void sendEvent(const ChangedElementsEvent & event) {
onElementsChanged(event.getListOld(), event.getListNew(),
event.getNewNumbering(), event);
}
template <class EventHandler> friend class EventHandlerManager;
/* ------------------------------------------------------------------------ */
/* Interface */
/* ------------------------------------------------------------------------ */
public:
/// function to implement to react on akantu::NewNodesEvent
virtual void onNodesAdded(const Array<UInt> & nodes_list,
const NewNodesEvent & event) = 0;
/// function to implement to react on akantu::RemovedNodesEvent
virtual void onNodesRemoved(const Array<UInt> & nodes_list,
const Array<UInt> & new_numbering,
const RemovedNodesEvent & event) = 0;
/// function to implement to react on akantu::NewElementsEvent
virtual void onElementsAdded(__attribute__((unused))
const Array<Element> & elements_list,
__attribute__((unused))
const NewElementsEvent & event) = 0;
/// function to implement to react on akantu::RemovedElementsEvent
virtual void onElementsRemoved(
__attribute__((unused)) const Array<Element> & elements_list,
__attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const RemovedElementsEvent & event) = 0;
/// function to implement to react on akantu::ChangedElementsEvent
virtual void onElementsChanged(
__attribute__((unused)) const Array<Element> & old_elements_list,
__attribute__((unused)) const Array<Element> & new_elements_list,
__attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const ChangedElementsEvent & event) = 0;
};
#endif /* __AKANTU_MESH_EVENTS_HH__ */
diff --git a/src/mesh/mesh_filter.hh b/src/mesh/mesh_filter.hh
index 5fc7ec1f5..862e0b817 100644
--- a/src/mesh/mesh_filter.hh
+++ b/src/mesh/mesh_filter.hh
@@ -1,75 +1,76 @@
/**
* @file mesh_filter.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Mon Feb 10 2014
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Dec 18 2015
*
* @brief the class representing the meshes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_FILTER_HH__
#define __AKANTU_MESH_FILTER_HH__
/* -------------------------------------------------------------------------- */
#include "element.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Filter Functors */
/* -------------------------------------------------------------------------- */
/// struct for the possible filter functors
struct FilterFunctor {
enum Type {
_node_filter_functor,
_element_filter_functor
};
};
/// class (functor) for the node filter
class NodeFilterFunctor : public FilterFunctor {
public:
bool operator()(UInt node) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
public:
static const Type type = _node_filter_functor;
};
/// class (functor) for the element filter
class ElementFilterFunctor : public FilterFunctor {
public:
bool operator()(const Element & element) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
public:
static const Type type = _element_filter_functor;
};
__END_AKANTU__
#endif /* __AKANTU_MESH_FILTER_HH__ */
diff --git a/src/mesh/mesh_inline_impl.cc b/src/mesh/mesh_inline_impl.cc
index 160b2ad57..7573dec32 100644
--- a/src/mesh/mesh_inline_impl.cc
+++ b/src/mesh/mesh_inline_impl.cc
@@ -1,600 +1,601 @@
/**
* @file mesh_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Thu Jul 15 2010
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Wed Nov 11 2015
*
* @brief Implementation of the inline functions of the mesh class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_COHESIVE_ELEMENT)
# include "cohesive_element.hh"
#endif
#ifndef __AKANTU_MESH_INLINE_IMPL_CC__
#define __AKANTU_MESH_INLINE_IMPL_CC__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline RemovedNodesEvent::RemovedNodesEvent(const Mesh & mesh) :
new_numbering(mesh.getNbNodes(), 1, "new_numbering") {
}
/* -------------------------------------------------------------------------- */
inline RemovedElementsEvent::RemovedElementsEvent(const Mesh & mesh, ID new_numbering_id) :
new_numbering(new_numbering_id, mesh.getID()) {
}
/* -------------------------------------------------------------------------- */
template <>
inline void Mesh::sendEvent<RemovedElementsEvent>(RemovedElementsEvent & event) {
connectivities.onElementsRemoved(event.getNewNumbering());
EventHandlerManager<MeshEventHandler>::sendEvent(event);
}
/* -------------------------------------------------------------------------- */
template <>
inline void Mesh::sendEvent<RemovedNodesEvent>(RemovedNodesEvent & event) {
if(created_nodes) removeNodesFromArray(*nodes , event.getNewNumbering());
if(nodes_global_ids) removeNodesFromArray(*nodes_global_ids, event.getNewNumbering());
if(nodes_type.getSize() != 0) removeNodesFromArray(nodes_type , event.getNewNumbering());
EventHandlerManager<MeshEventHandler>::sendEvent(event);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Mesh::removeNodesFromArray(Array<T> & vect, const Array<UInt> & new_numbering) {
Array<T> tmp(vect.getSize(), vect.getNbComponent());
UInt nb_component = vect.getNbComponent();
UInt new_nb_nodes = 0;
for (UInt i = 0; i < new_numbering.getSize(); ++i) {
UInt new_i = new_numbering(i);
if(new_i != UInt(-1)) {
memcpy(tmp.storage() + new_i * nb_component,
vect.storage() + i * nb_component,
nb_component * sizeof(T));
++new_nb_nodes;
}
}
tmp.resize(new_nb_nodes);
vect.copy(tmp);
}
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_CORE_CXX11
template <typename... Args>
inline void Mesh::translate(Args... params) {
// check that the number of parameters corresponds to the dimension
AKANTU_DEBUG_ASSERT(sizeof...(Args) <= spatial_dimension , "Number of arguments greater than dimension.");
// unpack parameters
Real s[] = { params... };
Array<Real>& nodes = getNodes();
for (UInt i = 0; i < nodes.getSize(); ++i)
for (UInt k = 0; k < sizeof...(Args); ++k)
nodes(i, k) += s[k];
}
#endif
/* -------------------------------------------------------------------------- */
inline UInt Mesh::elementToLinearized(const Element & elem) const {
AKANTU_DEBUG_ASSERT(elem.type < _max_element_type &&
elem.element < types_offsets.storage()[elem.type+1],
"The element " << elem
<< "does not exists in the mesh " << getID());
return types_offsets.storage()[elem.type] + elem.element;
}
/* -------------------------------------------------------------------------- */
inline Element Mesh::linearizedToElement (UInt linearized_element) const {
UInt t;
for (t = _not_defined;
t != _max_element_type && linearized_element >= types_offsets(t);
++t);
AKANTU_DEBUG_ASSERT(linearized_element < types_offsets(t),
"The linearized element " << linearized_element
<< "does not exists in the mesh " << getID());
--t;
ElementType type = ElementType(t);
return Element(type,
linearized_element - types_offsets.storage()[t],
_not_ghost,
getKind(type));
}
/* -------------------------------------------------------------------------- */
inline void Mesh::updateTypesOffsets(const GhostType & ghost_type) {
Array<UInt> * types_offsets_ptr = &this->types_offsets;
if(ghost_type == _ghost) types_offsets_ptr = &this->ghost_types_offsets;
Array<UInt> & types_offsets = *types_offsets_ptr;
types_offsets.clear();
type_iterator it = firstType(_all_dimensions, ghost_type, _ek_not_defined);
type_iterator last = lastType(_all_dimensions, ghost_type, _ek_not_defined);
for (; it != last; ++it)
types_offsets(*it) = connectivities(*it, ghost_type).getSize();
for (UInt t = _not_defined + 1; t < _max_element_type; ++t)
types_offsets(t) += types_offsets(t - 1);
for (UInt t = _max_element_type; t > _not_defined; --t)
types_offsets(t) = types_offsets(t - 1);
types_offsets(0) = 0;
}
/* -------------------------------------------------------------------------- */
inline const Mesh::ConnectivityTypeList & Mesh::getConnectivityTypeList(const GhostType & ghost_type) const {
if (ghost_type == _not_ghost)
return type_set;
else
return ghost_type_set;
}
/* -------------------------------------------------------------------------- */
inline Array<UInt> * Mesh::getNodesGlobalIdsPointer() {
AKANTU_DEBUG_IN();
if(nodes_global_ids == NULL) {
std::stringstream sstr; sstr << getID() << ":nodes_global_ids";
nodes_global_ids = &(alloc<UInt>(sstr.str(), nodes->getSize(), 1));
}
AKANTU_DEBUG_OUT();
return nodes_global_ids;
}
/* -------------------------------------------------------------------------- */
inline Array<Int> * Mesh::getNodesTypePointer() {
AKANTU_DEBUG_IN();
if(nodes_type.getSize() == 0) {
nodes_type.resize(nodes->getSize());
nodes_type.set(-1);
}
AKANTU_DEBUG_OUT();
return &nodes_type;
}
/* -------------------------------------------------------------------------- */
inline Array<UInt> * Mesh::getConnectivityPointer(const ElementType & type,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
Array<UInt> * tmp;
if(!connectivities.exists(type, ghost_type)) {
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
tmp = &(connectivities.alloc(0, nb_nodes_per_element,
type, ghost_type));
AKANTU_DEBUG_INFO("The connectivity vector for the type "
<< type << " created");
if (ghost_type == _not_ghost) type_set.insert(type);
else ghost_type_set.insert(type);
updateTypesOffsets(ghost_type);
} else {
tmp = &connectivities(type, ghost_type);
}
AKANTU_DEBUG_OUT();
return tmp;
}
/* -------------------------------------------------------------------------- */
inline Array< std::vector<Element> > * Mesh::getElementToSubelementPointer(const ElementType & type,
const GhostType & ghost_type) {
Array< std::vector<Element> > * tmp =
getDataPointer< std::vector<Element> >("element_to_subelement", type, ghost_type, 1, true);
return tmp;
}
/* -------------------------------------------------------------------------- */
inline Array<Element > * Mesh::getSubelementToElementPointer(const ElementType & type,
const GhostType & ghost_type) {
Array<Element> * tmp =
getDataPointer<Element>("subelement_to_element", type, ghost_type,
getNbFacetsPerElement(type), true, is_mesh_facets);
return tmp;
}
/* -------------------------------------------------------------------------- */
inline const Array< std::vector<Element> > & Mesh::getElementToSubelement(const ElementType & type,
const GhostType & ghost_type) const {
return getData< std::vector<Element> >("element_to_subelement", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline Array< std::vector<Element> > & Mesh::getElementToSubelement(const ElementType & type,
const GhostType & ghost_type) {
return getData< std::vector<Element> >("element_to_subelement", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline const Array<Element> & Mesh::getSubelementToElement(const ElementType & type,
const GhostType & ghost_type) const {
return getData<Element>("subelement_to_element", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline Array<Element> & Mesh::getSubelementToElement(const ElementType & type,
const GhostType & ghost_type) {
return getData<Element>("subelement_to_element", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline Array<T> * Mesh::getDataPointer(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type,
UInt nb_component,
bool size_to_nb_element,
bool resize_with_parent) {
Array<T> & tmp = mesh_data.getElementalDataArrayAlloc<T>(data_name,
el_type, ghost_type,
nb_component);
if (size_to_nb_element) {
if (resize_with_parent)
tmp.resize(mesh_parent->getNbElement(el_type, ghost_type));
else
tmp.resize(this->getNbElement(el_type, ghost_type));
} else {
tmp.resize(0);
}
return &tmp;
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline const Array<T> & Mesh::getData(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type) const {
return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline Array<T> & Mesh::getData(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type) {
return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline const ElementTypeMapArray<T> & Mesh::getData(const std::string & data_name) const {
return mesh_data.getElementalData<T>(data_name);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline ElementTypeMapArray<T> & Mesh::getData(const std::string & data_name) {
return mesh_data.getElementalData<T>(data_name);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline ElementTypeMapArray<T> & Mesh::registerData(const std::string & data_name) {
this->mesh_data.registerElementalData<T>(data_name);
return this->getData<T>(data_name);
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbElement(const ElementType & type,
const GhostType & ghost_type) const {
try {
const Array<UInt> & conn = connectivities(type, ghost_type);
return conn.getSize();
} catch (...) {
return 0;
}
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbElement(const UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & kind) const {
UInt nb_element = 0;
type_iterator it = firstType(spatial_dimension, ghost_type, kind);
type_iterator last = lastType(spatial_dimension, ghost_type, kind);
for (; it != last; ++it) nb_element += getNbElement(*it, ghost_type);
return nb_element;
}
/* -------------------------------------------------------------------------- */
inline void Mesh::getBarycenter(UInt element, const ElementType & type,
Real * barycenter,
GhostType ghost_type) const {
UInt * conn_val = getConnectivity(type, ghost_type).storage();
UInt nb_nodes_per_element = getNbNodesPerElement(type);
Real local_coord[spatial_dimension * nb_nodes_per_element];
UInt offset = element * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
memcpy(local_coord + n * spatial_dimension,
nodes->storage() + conn_val[offset + n] * spatial_dimension,
spatial_dimension*sizeof(Real));
}
Math::barycenter(local_coord, nb_nodes_per_element, spatial_dimension, barycenter);
}
/* -------------------------------------------------------------------------- */
inline void Mesh::getBarycenter(const Element & element, Vector<Real> & barycenter) const {
getBarycenter(element.element, element.type, barycenter.storage(), element.ghost_type);
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbNodesPerElement(const ElementType & type) {
UInt nb_nodes_per_element = 0;
#define GET_NB_NODES_PER_ELEMENT(type) \
nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_NODES_PER_ELEMENT);
#undef GET_NB_NODES_PER_ELEMENT
return nb_nodes_per_element;
}
/* -------------------------------------------------------------------------- */
inline ElementType Mesh::getP1ElementType(const ElementType & type) {
ElementType p1_type = _not_defined;
#define GET_P1_TYPE(type) \
p1_type = ElementClass<type>::getP1ElementType()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_P1_TYPE);
#undef GET_P1_TYPE
return p1_type;
}
/* -------------------------------------------------------------------------- */
inline ElementKind Mesh::getKind(const ElementType & type) {
ElementKind kind = _ek_not_defined;
#define GET_KIND(type) \
kind = ElementClass<type>::getKind()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_KIND);
#undef GET_KIND
return kind;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getSpatialDimension(const ElementType & type) {
UInt spatial_dimension = 0;
#define GET_SPATIAL_DIMENSION(type) \
spatial_dimension = ElementClass<type>::getSpatialDimension()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SPATIAL_DIMENSION);
#undef GET_SPATIAL_DIMENSION
return spatial_dimension;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbFacetTypes(const ElementType & type, UInt t) {
UInt nb = 0;
#define GET_NB_FACET_TYPE(type) \
nb = ElementClass<type>::getNbFacetTypes()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET_TYPE);
#undef GET_NB_FACET_TYPE
return nb;
}
/* -------------------------------------------------------------------------- */
inline ElementType Mesh::getFacetType(const ElementType & type, UInt t) {
ElementType surface_type = _not_defined;
#define GET_FACET_TYPE(type) \
surface_type = ElementClass<type>::getFacetType(t)
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_TYPE);
#undef GET_FACET_TYPE
return surface_type;
}
/* -------------------------------------------------------------------------- */
inline VectorProxy<ElementType> Mesh::getAllFacetTypes(const ElementType & type) {
#define GET_FACET_TYPE(type) \
UInt nb = ElementClass<type>::getNbFacetTypes(); \
ElementType * elt_ptr = const_cast<ElementType *>(ElementClass<type>::getFacetTypeInternal()); \
return VectorProxy<ElementType>(elt_ptr, nb);
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_TYPE);
#undef GET_FACET_TYPE
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbFacetsPerElement(const ElementType & type) {
AKANTU_DEBUG_IN();
UInt n_facet = 0;
#define GET_NB_FACET(type) \
n_facet = ElementClass<type>::getNbFacetsPerElement()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
#undef GET_NB_FACET
AKANTU_DEBUG_OUT();
return n_facet;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbFacetsPerElement(const ElementType & type, UInt t) {
AKANTU_DEBUG_IN();
UInt n_facet = 0;
#define GET_NB_FACET(type) \
n_facet = ElementClass<type>::getNbFacetsPerElement(t)
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
#undef GET_NB_FACET
AKANTU_DEBUG_OUT();
return n_facet;
}
/* -------------------------------------------------------------------------- */
inline MatrixProxy<UInt> Mesh::getFacetLocalConnectivity(const ElementType & type, UInt t) {
AKANTU_DEBUG_IN();
#define GET_FACET_CON(type) \
AKANTU_DEBUG_OUT(); \
return ElementClass<type>::getFacetLocalConnectivityPerElement(t)
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_CON);
#undef GET_FACET_CON
AKANTU_DEBUG_OUT();
return Matrix<UInt>(); // This avoid a compilation warning but will certainly
// also cause a segfault if reached
}
/* -------------------------------------------------------------------------- */
inline Matrix<UInt> Mesh::getFacetConnectivity(const Element & element, UInt t) const {
AKANTU_DEBUG_IN();
Matrix<UInt> local_facets(getFacetLocalConnectivity(element.type, t), false);
Matrix<UInt> facets(local_facets.rows(), local_facets.cols());
const Array<UInt> & conn = connectivities(element.type, element.ghost_type);
for (UInt f = 0; f < facets.rows(); ++f) {
for (UInt n = 0; n < facets.cols(); ++n) {
facets(f, n) = conn(element.element, local_facets(f, n));
}
}
AKANTU_DEBUG_OUT();
return facets;
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Mesh::extractNodalValuesFromElement(const Array<T> & nodal_values,
T * local_coord,
UInt * connectivity,
UInt n_nodes,
UInt nb_degree_of_freedom) const {
for (UInt n = 0; n < n_nodes; ++n) {
memcpy(local_coord + n * nb_degree_of_freedom,
nodal_values.storage() + connectivity[n] * nb_degree_of_freedom,
nb_degree_of_freedom * sizeof(T));
}
}
/* -------------------------------------------------------------------------- */
inline void Mesh::addConnectivityType(const ElementType & type,
const GhostType & ghost_type){
getConnectivityPointer(type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isPureGhostNode(UInt n) const {
return nodes_type.getSize() ? (nodes_type(n) == -3) : false;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isLocalOrMasterNode(UInt n) const {
return nodes_type.getSize() ? (nodes_type(n) == -2) || (nodes_type(n) == -1) : true;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isLocalNode(UInt n) const {
return nodes_type.getSize() ? nodes_type(n) == -1 : true;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isMasterNode(UInt n) const {
return nodes_type.getSize() ? nodes_type(n) == -2 : false;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isSlaveNode(UInt n) const {
return nodes_type.getSize() ? nodes_type(n) >= 0 : false;
}
/* -------------------------------------------------------------------------- */
inline Int Mesh::getNodeType(UInt local_id) const {
return nodes_type.getSize() ? nodes_type(local_id) : -1;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNodeGlobalId(UInt local_id) const {
return nodes_global_ids ? (*nodes_global_ids)(local_id) : local_id;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbGlobalNodes() const {
return nodes_global_ids ? nb_global_nodes : nodes->getSize();
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbNodesPerElementList(const Array<Element> & elements) {
UInt nb_nodes_per_element = 0;
UInt nb_nodes = 0;
ElementType current_element_type = _not_defined;
Array<Element>::const_iterator<Element> el_it = elements.begin();
Array<Element>::const_iterator<Element> el_end = elements.end();
for (; el_it != el_end; ++el_it) {
const Element & el = *el_it;
if(el.type != current_element_type) {
current_element_type = el.type;
nb_nodes_per_element = Mesh::getNbNodesPerElement(current_element_type);
}
nb_nodes += nb_nodes_per_element;
}
return nb_nodes;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_MESH_INLINE_IMPL_CC__ */
diff --git a/src/mesh/node_group.cc b/src/mesh/node_group.cc
index 04b54fefb..5bb93cec5 100644
--- a/src/mesh/node_group.cc
+++ b/src/mesh/node_group.cc
@@ -1,110 +1,111 @@
/**
* @file node_group.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Mon Jun 09 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Implementation of the node group
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "node_group.hh"
#include "dumpable.hh"
#include "dumpable_inline_impl.hh"
#include "mesh.hh"
#if defined(AKANTU_USE_IOHELPER)
# include "dumper_paraview.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
NodeGroup::NodeGroup(const std::string & name,
const Mesh & mesh,
const std::string & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
name(name),
node_group(alloc<UInt>(std::string(this->id + ":nodes"), 0, 1))//,
// mesh(mesh)
{
#if defined(AKANTU_USE_IOHELPER)
this->registerDumper<DumperParaview>("paraview_" + name, name, true);
this->getDumper().registerField("positions",new dumper::NodalField<Real,true>(
mesh.getNodes(),
0,
0,
&this->getNodes()));
#endif
}
/* -------------------------------------------------------------------------- */
NodeGroup::~NodeGroup() {}
/* -------------------------------------------------------------------------- */
void NodeGroup::empty() {
node_group.resize(0);
}
/* -------------------------------------------------------------------------- */
void NodeGroup::optimize() {
std::sort(node_group.begin(), node_group.end());
Array<UInt>::iterator<> end = std::unique(node_group.begin(), node_group.end());
node_group.resize(end - node_group.begin());
}
/* -------------------------------------------------------------------------- */
void NodeGroup::append(const NodeGroup & other_group) {
AKANTU_DEBUG_IN();
UInt nb_nodes = node_group.getSize();
/// append new nodes to current list
node_group.resize(nb_nodes + other_group.node_group.getSize());
std::copy(other_group.node_group.begin(),
other_group.node_group.end(),
node_group.begin() + nb_nodes);
optimize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NodeGroup::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "NodeGroup [" << std::endl;
stream << space << " + name: " << name << std::endl;
node_group.printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
__END_AKANTU__
diff --git a/src/mesh/node_group.hh b/src/mesh/node_group.hh
index 5b3a1e9b2..9143bb820 100644
--- a/src/mesh/node_group.hh
+++ b/src/mesh/node_group.hh
@@ -1,133 +1,134 @@
/**
* @file node_group.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Mon Jun 09 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Node group definition
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_array.hh"
#include "aka_memory.hh"
#include "mesh_filter.hh"
#include "dumpable.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NODE_GROUP_HH__
#define __AKANTU_NODE_GROUP_HH__
__BEGIN_AKANTU__
class NodeGroup : public Memory, public Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NodeGroup(const std::string & name,
const Mesh & mesh,
const std::string & id = "node_group",
const MemoryID & memory_id = 0);
virtual ~NodeGroup();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
typedef Array<UInt>::const_iterator<UInt> const_node_iterator;
/// empty the node group
void empty();
/// iterator to the beginning of the node group
inline const_node_iterator begin() const;
/// iterator to the end of the node group
inline const_node_iterator end() const;
/// add a node and give the local position through an iterator
inline const_node_iterator add(UInt node, bool check_for_duplicate = true);
/// remove duplicated nodes
void optimize();
/// append a group to current one
void append(const NodeGroup & other_group);
/// apply a filter on current node group
template <typename T>
void applyNodeFilter(T & filter);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO_NOT_CONST(Nodes, node_group, Array<UInt> &);
AKANTU_GET_MACRO(Nodes, node_group, const Array<UInt> &);
AKANTU_GET_MACRO(Name, name, const std::string &);
/// give the number of nodes in the current group
inline UInt getSize() const;
UInt * storage(){return node_group.storage();};
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// name of the group
std::string name;
/// list of nodes in the group
Array<UInt> & node_group;
/// reference to the mesh in question
//const Mesh & mesh;
};
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const NodeGroup & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "node_group_inline_impl.cc"
#endif /* __AKANTU_NODE_GROUP_HH__ */
diff --git a/src/mesh/node_group_inline_impl.cc b/src/mesh/node_group_inline_impl.cc
index 08d36c1fd..d0d676123 100644
--- a/src/mesh/node_group_inline_impl.cc
+++ b/src/mesh/node_group_inline_impl.cc
@@ -1,88 +1,89 @@
/**
* @file node_group_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Node group inline function definitions
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline NodeGroup::const_node_iterator NodeGroup::begin() const {
return node_group.begin();
}
/* -------------------------------------------------------------------------- */
inline NodeGroup::const_node_iterator NodeGroup::end() const {
return node_group.end();
}
/* -------------------------------------------------------------------------- */
inline NodeGroup::const_node_iterator NodeGroup::add(UInt node, bool check_for_duplicate) {
if(check_for_duplicate) {
const_node_iterator it = std::find(begin(), end(), node);
if(it == node_group.end()) {
node_group.push_back(node);
return (node_group.end() - 1);
}
return it;
} else {
node_group.push_back(node);
return (node_group.end() - 1);
}
}
/* -------------------------------------------------------------------------- */
inline UInt NodeGroup::getSize() const {
return node_group.getSize();
}
/* -------------------------------------------------------------------------- */
struct FilterFunctor;
template <typename T>
void NodeGroup::applyNodeFilter(T & filter) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(T::type == FilterFunctor::_node_filter_functor,
"NodeFilter can only apply node filter functor");
Array<UInt>::iterator<> it = this->node_group.begin();
for (; it != node_group.end(); ++it) {
/// filter == true -> keep node
if (!filter(*it)) {
it = node_group.erase(it);
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/mesh_utils/cohesive_element_inserter.cc b/src/mesh_utils/cohesive_element_inserter.cc
index 6fa11dc03..e20861cc5 100644
--- a/src/mesh_utils/cohesive_element_inserter.cc
+++ b/src/mesh_utils/cohesive_element_inserter.cc
@@ -1,426 +1,426 @@
/**
* @file cohesive_element_inserter.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Dec 04 2013
- * @date last modification: Tue Jul 29 2014
+ * @date last modification: Sun Oct 04 2015
*
* @brief Cohesive element inserter functions
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <algorithm>
#include <limits>
#include "cohesive_element_inserter.hh"
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
CohesiveElementInserter::CohesiveElementInserter(Mesh & mesh,
bool is_extrinsic,
DistributedSynchronizer * synchronizer,
const ID & id) :
id(id),
mesh(mesh),
mesh_facets(mesh.initMeshFacets()),
insertion_facets("insertion_facets", id),
insertion_limits(mesh.getSpatialDimension(), 2),
check_facets("check_facets", id) {
MeshUtils::buildAllFacets(mesh, mesh_facets, 0, synchronizer);
init(is_extrinsic);
}
/* -------------------------------------------------------------------------- */
CohesiveElementInserter::~CohesiveElementInserter() {
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
delete global_ids_updater;
#endif
}
/* -------------------------------------------------------------------------- */
void CohesiveElementInserter::init(bool is_extrinsic) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
MeshUtils::resetFacetToDouble(mesh_facets);
/// initialize facet insertion array
mesh_facets.initElementTypeMapArray(insertion_facets, 1,
spatial_dimension - 1,
false,
_ek_regular,
true);
/// init insertion limits
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
insertion_limits(dim, 0) = std::numeric_limits<Real>::max() * (-1.);
insertion_limits(dim, 1) = std::numeric_limits<Real>::max();
}
if (is_extrinsic) {
mesh_facets.initElementTypeMapArray(check_facets, 1, spatial_dimension - 1);
initFacetsCheck();
}
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
facet_synchronizer = NULL;
global_ids_updater = NULL;
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void CohesiveElementInserter::initFacetsCheck() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType facet_gt = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, facet_gt);
Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1, facet_gt);
for (; it != last; ++it) {
ElementType facet_type = *it;
Array<bool> & f_check = check_facets(facet_type, facet_gt);
const Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(facet_type, facet_gt);
UInt nb_facet = element_to_facet.getSize();
f_check.resize(nb_facet);
for (UInt f = 0; f < nb_facet; ++f) {
if (element_to_facet(f)[1] == ElementNull ||
(element_to_facet(f)[0].ghost_type == _ghost &&
element_to_facet(f)[1].ghost_type == _ghost)) {
f_check(f) = false;
}
else f_check(f) = true;
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void CohesiveElementInserter::limitCheckFacets() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
Vector<Real> bary_facet(spatial_dimension);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end();
++gt) {
GhostType ghost_type = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
Array<bool> & f_check = check_facets(type, ghost_type);
UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
for (UInt f = 0; f < nb_facet; ++f) {
if (f_check(f)) {
mesh_facets.getBarycenter(f, type, bary_facet.storage(), ghost_type);
UInt coord_in_limit = 0;
while (coord_in_limit < spatial_dimension &&
bary_facet(coord_in_limit) > insertion_limits(coord_in_limit, 0) &&
bary_facet(coord_in_limit) < insertion_limits(coord_in_limit, 1))
++coord_in_limit;
if (coord_in_limit != spatial_dimension)
f_check(f) = false;
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void CohesiveElementInserter::setLimit(SpacialDirection axis,
Real first_limit,
Real second_limit) {
AKANTU_DEBUG_ASSERT(axis < mesh.getSpatialDimension(),
"You are trying to limit insertion in a direction that doesn't exist");
insertion_limits(axis, 0) = std::min(first_limit, second_limit);
insertion_limits(axis, 1) = std::max(first_limit, second_limit);
}
/* -------------------------------------------------------------------------- */
void CohesiveElementInserter::insertIntrinsicElements() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
Vector<Real> bary_facet(spatial_dimension);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
for(; it != end; ++it) {
const ElementType type_facet = *it;
Array<bool> & f_insertion = insertion_facets(type_facet, ghost_type);
Array<std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, ghost_type);
UInt nb_facet = mesh_facets.getNbElement(type_facet, ghost_type);
for (UInt f = 0; f < nb_facet; ++f) {
if (element_to_facet(f)[1] == ElementNull) continue;
mesh_facets.getBarycenter(f, type_facet, bary_facet.storage(), ghost_type);
UInt coord_in_limit = 0;
while (coord_in_limit < spatial_dimension &&
bary_facet(coord_in_limit) > insertion_limits(coord_in_limit, 0) &&
bary_facet(coord_in_limit) < insertion_limits(coord_in_limit, 1))
++coord_in_limit;
if (coord_in_limit == spatial_dimension)
f_insertion(f) = true;
}
}
}
insertElements();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void CohesiveElementInserter::insertIntrinsicElements(std::string physname,
UInt material_index) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
ElementTypeMapArray<UInt> * phys_data;
try {
phys_data = &(mesh_facets.getData<UInt>("physical_names"));
}
catch(...){
phys_data = &(mesh_facets.registerData<UInt>("physical_names"));
mesh_facets.initElementTypeMapArray(*phys_data, 1, spatial_dimension-1, false, _ek_regular, true);
}
Vector<Real> bary_facet(spatial_dimension);
mesh_facets.createElementGroup(physname);
GhostType ghost_type = _not_ghost;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
for(; it != end; ++it) {
const ElementType type_facet = *it;
Array<bool> & f_insertion = insertion_facets(type_facet, ghost_type);
Array<std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, ghost_type);
UInt nb_facet = mesh_facets.getNbElement(type_facet, ghost_type);
UInt coord_in_limit = 0;
ElementGroup & group = mesh.getElementGroup(physname);
ElementGroup & group_facet = mesh_facets.getElementGroup(physname);
Vector<Real> bary_physgroup(spatial_dimension);
Real norm_bary;
for(ElementGroup::const_element_iterator el_it(group.element_begin
(type_facet, ghost_type));
el_it!= group.element_end(type_facet, ghost_type);
++el_it) {
UInt e = *el_it;
mesh.getBarycenter(e, type_facet, bary_physgroup.storage(), ghost_type);
bool find_a_partner = false;
norm_bary = bary_physgroup.norm();
Array<UInt> & material_id = (*phys_data)(type_facet, ghost_type);
for (UInt f = 0; f < nb_facet; ++f) {
if (element_to_facet(f)[1] == ElementNull) continue;
mesh_facets.getBarycenter(f, type_facet, bary_facet.storage(), ghost_type);
coord_in_limit = 0;
while (coord_in_limit < spatial_dimension &&
(std::abs(bary_facet(coord_in_limit)
- bary_physgroup(coord_in_limit))/norm_bary
< Math::getTolerance()))
++coord_in_limit;
if (coord_in_limit == spatial_dimension) {
f_insertion(f) = true;
find_a_partner = true;
group_facet.add(type_facet, f, ghost_type,false);
material_id(f) = material_index;
break;
}
}
AKANTU_DEBUG_ASSERT(find_a_partner,
"The element nO " << e
<< " of physical group " << physname
<< " did not find its associated facet!"
<< " Try to decrease math tolerance. "
<< std::endl);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
UInt CohesiveElementInserter::insertElements(bool only_double_facets) {
NewNodesEvent node_event;
node_event.getList().extendComponentsInterlaced(2, 1);
NewElementsEvent element_event;
UInt nb_new_elements = MeshUtils::insertCohesiveElements(mesh,
mesh_facets,
insertion_facets,
node_event.getList(),
element_event.getList(),
only_double_facets);
UInt nb_new_nodes = node_event.getList().getSize();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
if (mesh.getNodesType().getSize()) {
/// update nodes type
updateNodesType(mesh, node_event);
updateNodesType(mesh_facets, node_event);
/// update global ids
nb_new_nodes = updateGlobalIDs(node_event);
/// compute total number of new elements
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
comm.allReduce(&nb_new_elements, 1, _so_sum);
}
#endif
if (nb_new_nodes > 0)
mesh.sendEvent(node_event);
if (nb_new_elements > 0) {
updateInsertionFacets();
mesh.updateTypesOffsets(_not_ghost);
mesh.sendEvent(element_event);
MeshUtils::resetFacetToDouble(mesh_facets);
}
return nb_new_elements;
}
/* -------------------------------------------------------------------------- */
void CohesiveElementInserter::updateInsertionFacets() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType facet_gt = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, facet_gt);
Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1, facet_gt);
for (; it != last; ++it) {
ElementType facet_type = *it;
Array<bool> & ins_facets = insertion_facets(facet_type, facet_gt);
// this is the extrinsic case
if (check_facets.exists(facet_type, facet_gt)) {
Array<bool> & f_check = check_facets(facet_type, facet_gt);
UInt nb_facets = f_check.getSize();
for (UInt f = 0; f < ins_facets.getSize(); ++f) {
if (ins_facets(f)) {
++nb_facets;
ins_facets(f) = false;
f_check(f) = false;
}
}
f_check.resize(nb_facets);
}
// and this the intrinsic one
else {
ins_facets.resize(mesh_facets.getNbElement(facet_type, facet_gt));
ins_facets.set(false);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void CohesiveElementInserter::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "CohesiveElementInserter [" << std::endl;
stream << space << " + mesh [" << std::endl;
mesh.printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << " + mesh_facets [" << std::endl;
mesh_facets.printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << "]" << std::endl;
}
__END_AKANTU__
diff --git a/src/mesh_utils/cohesive_element_inserter.hh b/src/mesh_utils/cohesive_element_inserter.hh
index 6c1a14248..6fcea2724 100644
--- a/src/mesh_utils/cohesive_element_inserter.hh
+++ b/src/mesh_utils/cohesive_element_inserter.hh
@@ -1,204 +1,205 @@
/**
* @file cohesive_element_inserter.hh
*
+ * @author Fabian Barras <fabian.barras@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Dec 04 2013
- * @date last modification: Tue Jul 29 2014
+ * @date last modification: Fri Oct 02 2015
*
* @brief Cohesive element inserter
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
#define __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
/* -------------------------------------------------------------------------- */
#include <numeric>
#include "data_accessor.hh"
#include "mesh_utils.hh"
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
# include "global_ids_updater.hh"
# include "facet_synchronizer.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class CohesiveElementInserter : public DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
CohesiveElementInserter(Mesh & mesh,
bool is_extrinsic = false,
DistributedSynchronizer * synchronizer = NULL,
const ID & id = "cohesive_element_inserter");
virtual ~CohesiveElementInserter();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// init function
void init(bool is_extrinsic);
/// set range limitation for intrinsic cohesive element insertion
void setLimit(SpacialDirection axis, Real first_limit, Real second_limit);
/// insert intrinsic cohesive elements in a predefined range
void insertIntrinsicElements();
/// preset insertion of intrinsic cohesive elements along
/// a predefined group of facet and assign them a defined material index.
/// insertElement() method has to be called to finalize insertion.
void insertIntrinsicElements(std::string physname, UInt material_index);
/// insert extrinsic cohesive elements (returns the number of new
/// cohesive elements)
UInt insertElements(bool only_double_facets = false);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/// limit check facets to match given insertion limits
void limitCheckFacets();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
/// init parallel variables
void initParallel(FacetSynchronizer * facet_synchronizer,
DistributedSynchronizer * distributed_synchronizer);
#endif
protected:
/// init facets check
void initFacetsCheck();
/// update facet insertion arrays after facets doubling
void updateInsertionFacets();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
/// update nodes type and global ids for parallel simulations
UInt updateGlobalIDs(NewNodesEvent & node_event);
/// update nodes type
void updateNodesType(Mesh & mesh, NewNodesEvent & node_event);
/// functions for parallel communications
inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
template<bool pack_mode>
inline void packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
const Array<Element> & elements) const;
template<bool pack_mode>
inline void packUnpackGroupedInsertionData(CommunicationBuffer & buffer,
const Array<Element> & elements) const;
#endif
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO_NOT_CONST(InsertionFacetsByElement,
insertion_facets,
ElementTypeMapArray<bool> &);
AKANTU_GET_MACRO(InsertionFacetsByElement,
insertion_facets,
const ElementTypeMapArray<bool> &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(InsertionFacets, insertion_facets, bool);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(CheckFacets, check_facets, bool);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(CheckFacets, check_facets, bool);
AKANTU_GET_MACRO(MeshFacets, mesh_facets, const Mesh &);
AKANTU_GET_MACRO_NOT_CONST(MeshFacets, mesh_facets, Mesh &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// object id
ID id;
/// main mesh where to insert cohesive elements
Mesh & mesh;
/// mesh containing facets
Mesh & mesh_facets;
/// list of facets where to insert elements
ElementTypeMapArray<bool> insertion_facets;
/// limits for element insertion
Array<Real> insertion_limits;
/// vector containing facets in which extrinsic cohesive elements can be inserted
ElementTypeMapArray<bool> check_facets;
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
/// facet synchronizer
FacetSynchronizer * facet_synchronizer;
/// global connectivity ids updater
GlobalIdsUpdater * global_ids_updater;
#endif
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
# include "cohesive_element_inserter_inline_impl.cc"
#endif
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const CohesiveElementInserter & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__ */
diff --git a/src/mesh_utils/global_ids_updater.cc b/src/mesh_utils/global_ids_updater.cc
index 178abb647..00dfc0699 100644
--- a/src/mesh_utils/global_ids_updater.cc
+++ b/src/mesh_utils/global_ids_updater.cc
@@ -1,44 +1,48 @@
/**
* @file global_ids_updater.cc
+ *
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @date Fri Oct 2 13:44:02 2015
+ *
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Fri Oct 02 2015
*
* @brief Functions of the GlobalIdsUpdater
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "global_ids_updater.hh"
#include "mesh_utils.hh"
__BEGIN_AKANTU__
UInt GlobalIdsUpdater::updateGlobalIDs(UInt old_nb_nodes) {
UInt total_nb_new_nodes = MeshUtils::updateLocalMasterGlobalConnectivity(mesh, old_nb_nodes);
synchronizer->computeBufferSize(*this, _gst_giu_global_conn);
synchronizer->asynchronousSynchronize(*this, _gst_giu_global_conn);
synchronizer->waitEndSynchronize(*this, _gst_giu_global_conn);
return total_nb_new_nodes;
}
__END_AKANTU__
diff --git a/src/mesh_utils/global_ids_updater.hh b/src/mesh_utils/global_ids_updater.hh
index 380866a83..254b4c8dd 100644
--- a/src/mesh_utils/global_ids_updater.hh
+++ b/src/mesh_utils/global_ids_updater.hh
@@ -1,83 +1,85 @@
/**
* @file global_ids_updater.hh
+ *
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @date Fri Oct 2 13:21:44 2015
*
- * @brief Class that updates the global ids of new nodes that are
+ * @date creation: Fri Oct 02 2015
+ *
+ * @brief Class that updates the global ids of new nodes that are
* inserted in the mesh. The functions in this class must be called
* after updating the node types
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_GLOBAL_IDS_UPDATER_HH__
#define __AKANTU_GLOBAL_IDS_UPDATER_HH__
/* -------------------------------------------------------------------------- */
#include "data_accessor.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class GlobalIdsUpdater : public DataAccessor {
public:
GlobalIdsUpdater(Mesh & mesh, DistributedSynchronizer * synchronizer) :
mesh(mesh), synchronizer(synchronizer) {}
/// function to update the global connectivity of new inserted
/// nodes. It must be called after updating the node types.
UInt updateGlobalIDs(UInt old_nb_nodes);
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
inline virtual UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
inline virtual void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
inline virtual void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
template<bool pack_mode>
inline void packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
const Array<Element> & elements) const;
/* ------------------------------------------------------------------------ */
/* Members */
/* ------------------------------------------------------------------------ */
private:
/// Reference to the mesh to update
Mesh & mesh;
/// distributed synchronizer to communicate the connectivity
DistributedSynchronizer * synchronizer;
};
__END_AKANTU__
#include "global_ids_updater_inline_impl.cc"
#endif /* __AKANTU_GLOBAL_IDS_UPDATER_HH__ */
diff --git a/src/mesh_utils/global_ids_updater_inline_impl.cc b/src/mesh_utils/global_ids_updater_inline_impl.cc
index 05e7909a0..867a4eb24 100644
--- a/src/mesh_utils/global_ids_updater_inline_impl.cc
+++ b/src/mesh_utils/global_ids_updater_inline_impl.cc
@@ -1,120 +1,123 @@
/**
* @file global_ids_updater_inline_impl.cc
+ *
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @date Fri Oct 2 13:33:44 2015
+ *
+ * @date creation: Fri Oct 02 2015
+ * @date last modification: Sun Oct 04 2015
*
* @brief Implementation of the inline functions of GlobalIdsUpdater
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline UInt GlobalIdsUpdater::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
UInt size = 0;
if (elements.getSize() == 0) return size;
if (tag == _gst_giu_global_conn)
size += Mesh::getNbNodesPerElementList(elements) * sizeof(UInt);
return size;
}
/* -------------------------------------------------------------------------- */
inline void GlobalIdsUpdater::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
if (tag == _gst_giu_global_conn)
packUnpackGlobalConnectivity<true>(buffer, elements);
}
/* -------------------------------------------------------------------------- */
inline void GlobalIdsUpdater::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
if (tag == _gst_giu_global_conn)
packUnpackGlobalConnectivity<false>(buffer, elements);
}
/* -------------------------------------------------------------------------- */
template<bool pack_mode>
inline void GlobalIdsUpdater::packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
const Array<Element> & elements) const {
AKANTU_DEBUG_IN();
ElementType current_element_type = _not_defined;
GhostType current_ghost_type = _casper;
Array<UInt>::const_vector_iterator conn_begin;
UInt nb_nodes_per_elem = 0;
UInt index;
Array<UInt> & global_nodes_ids = mesh.getGlobalNodesIds();
Array<Element>::const_scalar_iterator it = elements.begin();
Array<Element>::const_scalar_iterator end = elements.end();
for (; it != end; ++it) {
const Element & el = *it;
if (el.type != current_element_type || el.ghost_type != current_ghost_type) {
current_element_type = el.type;
current_ghost_type = el.ghost_type;
const Array<UInt> & connectivity = mesh.getConnectivity(current_element_type,
current_ghost_type);
nb_nodes_per_elem = connectivity.getNbComponent();
conn_begin = connectivity.begin(nb_nodes_per_elem);
}
/// get element connectivity
const Vector<UInt> current_conn = conn_begin[el.element];
/// loop on all connectivity nodes
for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
UInt node = current_conn(n);
if (pack_mode) {
/// if node is local or master pack its global id, otherwise
/// dummy data
if (mesh.isLocalOrMasterNode(node))
index = global_nodes_ids(node);
else
index = UInt(-1);
buffer << index;
}
else {
buffer >> index;
/// update slave nodes' index
if (index != UInt(-1) && mesh.isSlaveNode(node))
global_nodes_ids(node) = index;
}
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/mesh_utils/mesh_partition.cc b/src/mesh_utils/mesh_partition.cc
index dedd7bf3d..2304c3e75 100644
--- a/src/mesh_utils/mesh_partition.cc
+++ b/src/mesh_utils/mesh_partition.cc
@@ -1,424 +1,425 @@
/**
* @file mesh_partition.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Aug 17 2010
- * @date last modification: Mon Jul 21 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief implementation of common part of all partitioner
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "mesh_partition.hh"
#include "mesh_utils.hh"
#include "aka_types.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
MeshPartition::MeshPartition(const Mesh & mesh, UInt spatial_dimension,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
mesh(mesh), spatial_dimension(spatial_dimension),
partitions ("partition" , id, memory_id),
ghost_partitions ("ghost_partition" , id, memory_id),
ghost_partitions_offset("ghost_partition_offset", id, memory_id),
saved_connectivity("saved_connectivity", id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
MeshPartition::~MeshPartition() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* conversion in c++ of the GENDUALMETIS (mesh.c) function wrote by George in
* Metis (University of Minnesota)
*/
void MeshPartition::buildDualGraph(Array<Int> & dxadj, Array<Int> & dadjncy,
Array<Int> & edge_loads,
const EdgeLoadFunctor & edge_load_func) {
AKANTU_DEBUG_IN();
// tweak mesh;
const Mesh::ConnectivityTypeList & type_list = mesh.getConnectivityTypeList();
UInt nb_types = type_list.size();
UInt nb_good_types = 0;
UInt nb_nodes_per_element_p1[nb_types];
UInt magic_number[nb_types];
// UInt * conn_val[nb_types];
UInt nb_element[nb_types];
Array<UInt> * conn[nb_types];
Array<Element> lin_to_element;
Element elem;
elem.ghost_type = _not_ghost;
const_cast<Mesh &>(mesh).updateTypesOffsets(_not_ghost);
const_cast<Mesh &>(mesh).updateTypesOffsets(_ghost);
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it) {
ElementType type = *it;
if(Mesh::getSpatialDimension(type) != mesh.getSpatialDimension()) continue;
elem.type = type;
ElementType type_p1 = Mesh::getP1ElementType(type);
nb_nodes_per_element_p1[nb_good_types] = Mesh::getNbNodesPerElement(type_p1);
nb_element[nb_good_types] = mesh.getConnectivity(type, _not_ghost).getSize();
magic_number[nb_good_types] =
Mesh::getNbNodesPerElement(Mesh::getFacetType(type_p1));
conn[nb_good_types] = &const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
for (UInt i = 0; i < nb_element[nb_good_types]; ++i) {
elem.element = i;
lin_to_element.push_back(elem);
}
nb_good_types++;
}
CSR<UInt> node_to_elem;
MeshUtils::buildNode2Elements(mesh, node_to_elem);
UInt nb_total_element = 0;
UInt nb_total_node_element = 0;
for (UInt t = 0; t < nb_good_types; ++t) {
nb_total_element += nb_element[t];
nb_total_node_element += nb_element[t]*nb_nodes_per_element_p1[t];
}
dxadj.resize(nb_total_element + 1);
/// initialize the dxadj array
for (UInt t = 0, linerized_el = 0; t < nb_good_types; ++t)
for (UInt el = 0; el < nb_element[t]; ++el, ++linerized_el)
dxadj(linerized_el) = nb_nodes_per_element_p1[t];
/// convert the dxadj_val array in a csr one
for (UInt i = 1; i < nb_total_element; ++i) dxadj(i) += dxadj(i-1);
for (UInt i = nb_total_element; i > 0; --i) dxadj(i) = dxadj(i-1);
dxadj(0) = 0;
dadjncy.resize(2*dxadj(nb_total_element));
edge_loads.resize(2*dxadj(nb_total_element));
/// weight map to determine adjacency
unordered_map<UInt, UInt>::type weight_map;
for (UInt t = 0, linerized_el = 0; t < nb_good_types; ++t) {
for (UInt el = 0; el < nb_element[t]; ++el, ++linerized_el) {
/// fill the weight map
for (UInt n = 0; n < nb_nodes_per_element_p1[t]; ++n) {
UInt node = (*conn[t])(el, n);
CSR<UInt>::iterator k;
for (k = node_to_elem.rbegin(node); k != node_to_elem.rend(node); --k) {
UInt current_el = *k;
if(current_el <= linerized_el) break;
unordered_map<UInt, UInt>::type::iterator it_w;
it_w = weight_map.find(current_el);
if(it_w == weight_map.end()) {
weight_map[current_el] = 1;
} else {
it_w->second++;
}
}
}
/// each element with a weight of the size of a facet are adjacent
unordered_map<UInt, UInt>::type::iterator it_w;
for(it_w = weight_map.begin(); it_w != weight_map.end(); ++it_w) {
if(it_w->second == magic_number[t]) {
UInt adjacent_el = it_w->first;
#if defined(AKANTU_COHESIVE_ELEMENT)
/// Patch in order to prevent neighboring cohesive elements
/// from detecting each other
ElementKind linearized_el_kind = mesh.linearizedToElement(linerized_el).kind;
ElementKind adjacent_el_kind = mesh.linearizedToElement(adjacent_el).kind;
if (linearized_el_kind == adjacent_el_kind &&
linearized_el_kind == _ek_cohesive) continue;
#endif
UInt index_adj = dxadj(adjacent_el )++;
UInt index_lin = dxadj(linerized_el)++;
dadjncy(index_lin) = adjacent_el;
dadjncy(index_adj) = linerized_el;
}
}
weight_map.clear();
}
}
Int k_start = 0;
for (UInt t = 0, linerized_el = 0, j = 0; t < nb_good_types; ++t)
for (UInt el = 0; el < nb_element[t]; ++el, ++linerized_el) {
for (Int k = k_start; k < dxadj(linerized_el); ++k, ++j)
dadjncy(j) = dadjncy(k);
dxadj(linerized_el) = j;
k_start += nb_nodes_per_element_p1[t];
}
for (UInt i = nb_total_element; i > 0; --i) dxadj(i) = dxadj(i - 1);
dxadj(0) = 0;
UInt adj = 0;
for (UInt i = 0; i < nb_total_element; ++i) {
UInt nb_adj = dxadj(i + 1) - dxadj(i);
for (UInt j = 0; j < nb_adj; ++j, ++adj) {
Int el_adj_id = dadjncy(dxadj(i) + j);
Element el = lin_to_element(i);
Element el_adj = lin_to_element(el_adj_id);
Int load = edge_load_func(el, el_adj);
edge_loads(adj) = load;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartition::fillPartitionInformation(const Mesh & mesh,
const Int * linearized_partitions) {
AKANTU_DEBUG_IN();
CSR<UInt> node_to_elem;
MeshUtils::buildNode2Elements(mesh, node_to_elem);
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
_not_ghost,
_ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension,
_not_ghost,
_ek_not_defined);
UInt linearized_el = 0;
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
partitions .alloc(nb_element, 1, type, _not_ghost);
CSR<UInt> & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
ghost_part_csr.resizeRows(nb_element);
ghost_partitions_offset.alloc(nb_element + 1, 1, type, _ghost);
ghost_partitions .alloc(0, 1, type, _ghost);
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
for (UInt el = 0; el < nb_element; ++el, ++linearized_el) {
UInt part = linearized_partitions[linearized_el];
partitions(type, _not_ghost)(el) = part;
std::list<UInt> list_adj_part;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity.storage()[el * nb_nodes_per_element + n];
CSR<UInt>::iterator ne;
for (ne = node_to_elem.begin(node); ne != node_to_elem.end(node); ++ne) {
UInt adj_el = *ne;
UInt adj_part = linearized_partitions[adj_el];
if(part != adj_part) {
list_adj_part.push_back(adj_part);
}
}
}
list_adj_part.sort();
list_adj_part.unique();
for(std::list<UInt>::iterator adj_it = list_adj_part.begin();
adj_it != list_adj_part.end();
++adj_it) {
ghost_part_csr.getRows().push_back(*adj_it);
ghost_part_csr.rowOffset(el)++;
ghost_partitions(type, _ghost).push_back(*adj_it);
ghost_partitions_offset(type, _ghost)(el)++;
}
}
ghost_part_csr.countToCSR();
/// convert the ghost_partitions_offset array in an offset array
Array<UInt> & ghost_partitions_offset_ptr = ghost_partitions_offset(type, _ghost);
for (UInt i = 1; i < nb_element; ++i)
ghost_partitions_offset_ptr(i) += ghost_partitions_offset_ptr(i-1);
for (UInt i = nb_element; i > 0; --i)
ghost_partitions_offset_ptr(i) = ghost_partitions_offset_ptr(i-1);
ghost_partitions_offset_ptr(0) = 0;
}
// All Facets
for(Int sp = spatial_dimension - 1; sp >= 0; --sp) {
Mesh::type_iterator fit = mesh.firstType(sp,
_not_ghost,
_ek_not_defined);
Mesh::type_iterator fend = mesh.lastType(sp,
_not_ghost,
_ek_not_defined);
for(; fit != fend; ++fit) {
ElementType type = *fit;
UInt nb_element = mesh.getNbElement(type);
partitions .alloc(nb_element, 1, type, _not_ghost);
AKANTU_DEBUG_INFO("Allocating partitions for " << type);
CSR<UInt> & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
ghost_part_csr.resizeRows(nb_element);
ghost_partitions_offset.alloc(nb_element + 1, 1, type, _ghost);
ghost_partitions .alloc(0, 1, type, _ghost);
AKANTU_DEBUG_INFO("Allocating ghost_partitions for " << type);
const Array< std::vector<Element> > & elem_to_subelem = mesh.getElementToSubelement(type, _not_ghost);
for(UInt i(0); i < mesh.getNbElement(type, _not_ghost); ++i) { // Facet loop
const std::vector<Element> & adjacent_elems = elem_to_subelem(i);
if(!adjacent_elems.empty()) {
Element min_elem;
UInt min_part(std::numeric_limits<UInt>::max());
std::set<UInt> adjacent_parts;
for(UInt j(0); j < adjacent_elems.size(); ++j) {
UInt adjacent_elem_id = adjacent_elems[j].element;
UInt adjacent_elem_part = partitions(adjacent_elems[j].type, adjacent_elems[j].ghost_type)(adjacent_elem_id);
if(adjacent_elem_part < min_part) {
min_part = adjacent_elem_part;
min_elem = adjacent_elems[j];
}
adjacent_parts.insert(adjacent_elem_part);
}
partitions(type, _not_ghost)(i) = min_part;
CSR<UInt>::iterator git = ghost_partitions_csr(min_elem.type, _not_ghost).begin(min_elem.element);
CSR<UInt>::iterator gend = ghost_partitions_csr(min_elem.type, _not_ghost).end(min_elem.element);
for(; git != gend; ++git) {
adjacent_parts.insert(*git);
}
adjacent_parts.erase(min_part);
std::set<UInt>::const_iterator pit = adjacent_parts.begin();
std::set<UInt>::const_iterator pend = adjacent_parts.end();
for(; pit != pend; ++pit) {
ghost_part_csr.getRows().push_back(*pit);
ghost_part_csr.rowOffset(i)++;
ghost_partitions(type, _ghost).push_back(*pit);
}
ghost_partitions_offset(type, _ghost)(i+1) = ghost_partitions_offset(type, _ghost)(i+1)
+ adjacent_elems.size();
} else {
partitions(type, _not_ghost)(i) = 0;
}
}
ghost_part_csr.countToCSR();
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartition::tweakConnectivity(const Array<UInt> & pairs) {
AKANTU_DEBUG_IN();
if(pairs.getSize() == 0) return;
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
_not_ghost,
_ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension,
_not_ghost,
_ek_not_defined);
for(; it != end; ++it) {
ElementType type = *it;
Array<UInt> & conn = const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
UInt nb_nodes_per_element = conn.getNbComponent();
UInt nb_element = conn.getSize();
Array<UInt> & saved_conn = saved_connectivity.alloc(nb_element, nb_nodes_per_element, type, _not_ghost);
saved_conn.copy(conn);
for (UInt i = 0; i < pairs.getSize(); ++i) {
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
if(pairs(i, 1) == conn(el, n))
conn(el, n) = pairs(i, 0);
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartition::restoreConnectivity() {
AKANTU_DEBUG_IN();
ElementTypeMapArray<UInt>::type_iterator it = saved_connectivity.firstType(spatial_dimension,
_not_ghost,
_ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end = saved_connectivity.lastType(spatial_dimension,
_not_ghost,
_ek_not_defined);
for(; it != end; ++it) {
ElementType type = *it;
Array<UInt> & conn = const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
Array<UInt> & saved_conn = saved_connectivity(type, _not_ghost);
conn.copy(saved_conn);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/mesh_utils/mesh_partition.hh b/src/mesh_utils/mesh_partition.hh
index 62cb97ec8..600f73ee4 100644
--- a/src/mesh_utils/mesh_partition.hh
+++ b/src/mesh_utils/mesh_partition.hh
@@ -1,149 +1,150 @@
/**
* @file mesh_partition.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Aug 16 2010
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Sep 01 2015
*
* @brief tools to partitionate a mesh
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_PARTITION_HH__
#define __AKANTU_MESH_PARTITION_HH__
/* -------------------------------------------------------------------------- */
#include "aka_memory.hh"
#include "aka_csr.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class MeshPartition : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshPartition(const Mesh & mesh, UInt spatial_dimension,
const ID & id = "MeshPartitioner",
const MemoryID & memory_id = 0);
virtual ~MeshPartition();
class EdgeLoadFunctor {
public:
virtual Int operator()(__attribute__((unused)) const Element & el1,
__attribute__((unused)) const Element & el2) const = 0;
};
class ConstEdgeLoadFunctor : public EdgeLoadFunctor {
public:
virtual inline Int operator()(__attribute__((unused)) const Element & el1,
__attribute__((unused)) const Element & el2) const {
return 1;
}
};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// define a partition of the mesh
virtual void partitionate(UInt nb_part,
const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
const Array<UInt> & pairs = Array<UInt>()) = 0;
/// reorder the nodes to reduce the filling during the factorization of a
/// matrix that has a profil based on the connectivity of the mesh
virtual void reorder() = 0;
/// fill the partitions array with a given linearized partition information
void fillPartitionInformation(const Mesh & mesh, const Int * linearized_partitions);
protected:
/// build the dual graph of the mesh, for all element of spatial_dimension
void buildDualGraph(Array<Int> & dxadj, Array<Int> & dadjncy,
Array<Int> & edge_loads,
const EdgeLoadFunctor & edge_load_func);
/// tweak the mesh to handle the PBC pairs
void tweakConnectivity(const Array<UInt> & pairs);
/// restore the mesh that has been tweaked
void restoreConnectivity();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Partitions, partitions, const ElementTypeMapArray<UInt> &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Partition, partitions, UInt);
AKANTU_GET_MACRO(GhostPartitionCSR, ghost_partitions_csr, const ElementTypeMap< CSR<UInt> > &);
AKANTU_GET_MACRO(NbPartition, nb_partitions, UInt);
AKANTU_SET_MACRO(NbPartition, nb_partitions, UInt);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// id
std::string id;
/// the mesh to partition
const Mesh & mesh;
/// dimension of the elements to consider in the mesh
UInt spatial_dimension;
/// number of partitions
UInt nb_partitions;
/// partition numbers
ElementTypeMapArray<UInt> partitions;
ElementTypeMap< CSR<UInt> > ghost_partitions_csr;
ElementTypeMapArray<UInt> ghost_partitions;
ElementTypeMapArray<UInt> ghost_partitions_offset;
Array<UInt> * permutation;
ElementTypeMapArray<UInt> saved_connectivity;
};
__END_AKANTU__
#ifdef AKANTU_USE_SCOTCH
#include "mesh_partition_scotch.hh"
#endif
#endif /* __AKANTU_MESH_PARTITION_HH__ */
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
index d234d80e3..9023448b7 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
+++ b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
@@ -1,138 +1,138 @@
/**
* @file mesh_partition_mesh_data.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri May 03 2013
- * @date last modification: Thu Jul 31 2014
+ * @date last modification: Wed Nov 11 2015
*
* @brief implementation of the MeshPartitionMeshData class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "mesh_partition_mesh_data.hh"
#if !defined(AKANTU_NDEBUG)
#include <set>
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
MeshPartitionMeshData::MeshPartitionMeshData(const Mesh & mesh, UInt spatial_dimension,
const ID & id,
const MemoryID & memory_id) :
MeshPartition(mesh, spatial_dimension, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
MeshPartitionMeshData::MeshPartitionMeshData(const Mesh & mesh,
const ElementTypeMapArray<UInt> & mapping,
UInt spatial_dimension,
const ID & id,
const MemoryID & memory_id) :
MeshPartition(mesh, spatial_dimension, id, memory_id), partition_mapping(&mapping) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::partitionate(UInt nb_part,
const EdgeLoadFunctor & edge_load_func,
const Array<UInt> & pairs) {
AKANTU_DEBUG_IN();
tweakConnectivity(pairs);
nb_partitions = nb_part;
GhostType ghost_type = _not_ghost;
UInt spatial_dimension = mesh.getSpatialDimension();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type,
_ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension,
ghost_type,
_ek_not_defined);
UInt linearized_el = 0;
UInt nb_elements = mesh.getNbElement(mesh.getSpatialDimension(), ghost_type);
Int * partition_list = new Int[nb_elements];
#if !defined(AKANTU_NDEBUG)
std::set<UInt> partitions;
#endif
for(; it != end; ++it) {
ElementType type = *it;
const Array<UInt> & partition_array = (*partition_mapping)(type, ghost_type);
Array<UInt>::const_iterator< Vector<UInt> > p_it = partition_array.begin(1);
Array<UInt>::const_iterator< Vector<UInt> > p_end = partition_array.end(1);
AKANTU_DEBUG_ASSERT(UInt(p_end - p_it) == mesh.getNbElement(type, ghost_type),
"The partition mapping does not have the right number "
<< "of entries for type " << type << " and ghost type "
<< ghost_type << "." << " Tags=" << p_end-p_it
<< " Mesh=" << mesh.getNbElement(type, ghost_type));
for(; p_it != p_end; ++p_it, ++linearized_el) {
partition_list[linearized_el] = (*p_it)(0);
#if !defined(AKANTU_NDEBUG)
partitions.insert((*p_it)(0));
#endif
}
}
#if !defined(AKANTU_NDEBUG)
AKANTU_DEBUG_ASSERT(partitions.size() == nb_part, "The number of real partitions does not match with the number of asked partitions");
#endif
fillPartitionInformation(mesh, partition_list);
delete[] partition_list;
restoreConnectivity();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::reorder() {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::setPartitionMapping(const ElementTypeMapArray<UInt> & mapping) {
partition_mapping = &mapping;
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::setPartitionMappingFromMeshData(const std::string & data_name) {
partition_mapping = &(mesh.getData<UInt>(data_name));
}
__END_AKANTU__
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
index a68aee771..aab69b9e5 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
+++ b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
@@ -1,97 +1,98 @@
/**
* @file mesh_partition_mesh_data.hh
*
* @author Dana Christen <dana.christen@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief mesh partitioning based on data provided in the mesh
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_PARTITION_MESH_DATA_HH__
#define __AKANTU_MESH_PARTITION_MESH_DATA_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_partition.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class MeshPartitionMeshData : public MeshPartition {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshPartitionMeshData(const Mesh & mesh, UInt spatial_dimension,
const ID & id = "MeshPartitionerMeshData",
const MemoryID & memory_id = 0);
MeshPartitionMeshData(const Mesh & mesh,
const ElementTypeMapArray<UInt> & mapping,
UInt spatial_dimension,
const ID & id = "MeshPartitionerMeshData",
const MemoryID & memory_id = 0);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void partitionate(UInt nb_part,
const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
const Array<UInt> & pairs = Array<UInt>());
virtual void reorder();
void setPartitionMapping(const ElementTypeMapArray<UInt> & mapping);
void setPartitionMappingFromMeshData(const std::string & data_name);
private:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
const ElementTypeMapArray<UInt> * partition_mapping;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_MESH_PARTITION_MESH_DATA_HH__ */
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc b/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
index cc73b1b82..dd7d0dda8 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
+++ b/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
@@ -1,479 +1,480 @@
/**
* @file mesh_partition_scotch.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Aug 17 2010
- * @date last modification: Thu Mar 27 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief implementation of the MeshPartitionScotch class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <cstdio>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_partition_scotch.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#if ! defined(AKANTU_USE_PTSCOTCH)
# ifndef AKANTU_SCOTCH_NO_EXTERN
extern "C" {
# endif //AKANTU_SCOTCH_NO_EXTERN
# include <scotch.h>
# ifndef AKANTU_SCOTCH_NO_EXTERN
}
# endif //AKANTU_SCOTCH_NO_EXTERN
#else //AKANTU_USE_PTSCOTCH
# include <ptscotch.h>
#endif //AKANTU_USE_PTSCOTCH
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
MeshPartitionScotch::MeshPartitionScotch(const Mesh & mesh, UInt spatial_dimension,
const ID & id, const MemoryID & memory_id) :
MeshPartition(mesh, spatial_dimension, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
static SCOTCH_Mesh * createMesh(const Mesh & mesh) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes = mesh.getNbNodes();
UInt total_nb_element = 0;
UInt nb_edge = 0;
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator end = mesh.lastType(spatial_dimension);
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
total_nb_element += nb_element;
nb_edge += nb_element * nb_nodes_per_element;
}
SCOTCH_Num vnodbas = 0;
SCOTCH_Num vnodnbr = nb_nodes;
SCOTCH_Num velmbas = vnodnbr;
SCOTCH_Num velmnbr = total_nb_element;
SCOTCH_Num * verttab = new SCOTCH_Num[vnodnbr + velmnbr + 1];
SCOTCH_Num * vendtab = verttab + 1;
SCOTCH_Num * velotab = NULL;
SCOTCH_Num * vnlotab = NULL;
SCOTCH_Num * vlbltab = NULL;
memset(verttab, 0, (vnodnbr + velmnbr + 1) * sizeof(SCOTCH_Num));
it = mesh.firstType(spatial_dimension);
for(; it != end; ++it) {
ElementType type = *it;
if(Mesh::getSpatialDimension(type) != spatial_dimension) continue;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
/// count number of occurrence of each node
for (UInt el = 0; el < nb_element; ++el) {
UInt * conn_val = connectivity.storage() + el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
verttab[*(conn_val++)]++;
}
}
}
/// convert the occurrence array in a csr one
for (UInt i = 1; i < nb_nodes; ++i) verttab[i] += verttab[i-1];
for (UInt i = nb_nodes; i > 0; --i) verttab[i] = verttab[i-1];
verttab[0] = 0;
/// rearrange element to get the node-element list
SCOTCH_Num edgenbr = verttab[vnodnbr] + nb_edge;
SCOTCH_Num * edgetab = new SCOTCH_Num[edgenbr];
UInt linearized_el = 0;
it = mesh.firstType(spatial_dimension);
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
for (UInt el = 0; el < nb_element; ++el, ++linearized_el) {
UInt * conn_val = connectivity.storage() + el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n)
edgetab[verttab[*(conn_val++)]++] = linearized_el + velmbas;
}
}
for (UInt i = nb_nodes; i > 0; --i) verttab[i] = verttab[i-1];
verttab[0] = 0;
SCOTCH_Num * verttab_tmp = verttab + vnodnbr + 1;
SCOTCH_Num * edgetab_tmp = edgetab + verttab[vnodnbr];
it = mesh.firstType(spatial_dimension);
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
for (UInt el = 0; el < nb_element; ++el) {
*verttab_tmp = *(verttab_tmp - 1) + nb_nodes_per_element;
verttab_tmp++;
UInt * conn = connectivity.storage() + el * nb_nodes_per_element;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
*(edgetab_tmp++) = *(conn++) + vnodbas;
}
}
}
SCOTCH_Mesh * meshptr = new SCOTCH_Mesh;
SCOTCH_meshInit(meshptr);
SCOTCH_meshBuild(meshptr,
velmbas, vnodbas,
velmnbr, vnodnbr,
verttab, vendtab,
velotab, vnlotab,
vlbltab,
edgenbr, edgetab);
/// Check the mesh
AKANTU_DEBUG_ASSERT(SCOTCH_meshCheck(meshptr) == 0,
"Scotch mesh is not consistent");
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
/// save initial graph
FILE *fmesh = fopen("ScotchMesh.msh", "w");
SCOTCH_meshSave(meshptr, fmesh);
fclose(fmesh);
/// write geometry file
std::ofstream fgeominit;
fgeominit.open("ScotchMesh.xyz");
fgeominit << spatial_dimension << std::endl << nb_nodes << std::endl;
const Array<Real> & nodes = mesh.getNodes();
Real * nodes_val = nodes.storage();
for (UInt i = 0; i < nb_nodes; ++i) {
fgeominit << i << " ";
for (UInt s = 0; s < spatial_dimension; ++s)
fgeominit << *(nodes_val++) << " ";
fgeominit << std::endl;;
}
fgeominit.close();
}
#endif
AKANTU_DEBUG_OUT();
return meshptr;
}
/* -------------------------------------------------------------------------- */
static void destroyMesh(SCOTCH_Mesh * meshptr) {
AKANTU_DEBUG_IN();
SCOTCH_Num velmbas, vnodbas,
vnodnbr, velmnbr,
*verttab, *vendtab,
*velotab, *vnlotab,
*vlbltab,
edgenbr, *edgetab,
degrptr;
SCOTCH_meshData(meshptr,
&velmbas, &vnodbas,
&velmnbr, &vnodnbr,
&verttab, &vendtab,
&velotab, &vnlotab,
&vlbltab,
&edgenbr, &edgetab,
&degrptr);
delete [] verttab;
delete [] edgetab;
SCOTCH_meshExit(meshptr);
delete meshptr;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionScotch::partitionate(UInt nb_part,
const EdgeLoadFunctor & edge_load_func,
const Array<UInt> & pairs) {
AKANTU_DEBUG_IN();
nb_partitions = nb_part;
tweakConnectivity(pairs);
AKANTU_DEBUG_INFO("Partitioning the mesh " << mesh.getID()
<< " in " << nb_part << " parts.");
Array<Int> dxadj;
Array<Int> dadjncy;
Array<Int> edge_loads;
buildDualGraph(dxadj, dadjncy, edge_loads, edge_load_func);
/// variables that will hold our structures in scotch format
SCOTCH_Graph scotch_graph;
SCOTCH_Strat scotch_strat;
/// description number and arrays for struct mesh for scotch
SCOTCH_Num baseval = 0; //base numbering for element and
//nodes (0 -> C , 1 -> fortran)
SCOTCH_Num vertnbr = dxadj.getSize() - 1; //number of vertexes
SCOTCH_Num *parttab; //array of partitions
SCOTCH_Num edgenbr = dxadj(vertnbr); //twice the number of "edges"
//(an "edge" bounds two nodes)
SCOTCH_Num * verttab = dxadj.storage(); //array of start indices in edgetab
SCOTCH_Num * vendtab = NULL; //array of after-last indices in edgetab
SCOTCH_Num * velotab = NULL; //integer load associated with
//every vertex ( optional )
SCOTCH_Num * edlotab = edge_loads.storage(); //integer load associated with
//every edge ( optional )
SCOTCH_Num * edgetab = dadjncy.storage(); // adjacency array of every vertex
SCOTCH_Num * vlbltab = NULL; // vertex label array (optional)
/// Allocate space for Scotch arrays
parttab = new SCOTCH_Num[vertnbr];
/// Initialize the strategy structure
SCOTCH_stratInit (&scotch_strat);
/// Initialize the graph structure
SCOTCH_graphInit(&scotch_graph);
/// Build the graph from the adjacency arrays
SCOTCH_graphBuild(&scotch_graph, baseval,
vertnbr, verttab, vendtab,
velotab, vlbltab, edgenbr,
edgetab, edlotab);
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
/// save initial graph
FILE *fgraphinit = fopen("GraphIniFile.grf", "w");
SCOTCH_graphSave(&scotch_graph, fgraphinit);
fclose(fgraphinit);
/// write geometry file
std::ofstream fgeominit;
fgeominit.open("GeomIniFile.xyz");
fgeominit << spatial_dimension << std::endl << vertnbr << std::endl;
const Array<Real> & nodes = mesh.getNodes();
Mesh::type_iterator f_it = mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
Mesh::type_iterator f_end = mesh.lastType(spatial_dimension, _not_ghost, _ek_not_defined);
UInt out_linerized_el = 0;
for(; f_it != f_end; ++f_it) {
ElementType type = *f_it;
UInt nb_element = mesh.getNbElement(*f_it);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Real mid[spatial_dimension] ;
for (UInt el = 0; el < nb_element; ++el) {
memset(mid, 0, spatial_dimension*sizeof(Real));
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity.storage()[nb_nodes_per_element * el + n];
for (UInt s = 0; s < spatial_dimension; ++s)
mid[s] += ((Real) nodes.storage()[node * spatial_dimension + s]) / ((Real) nb_nodes_per_element);
}
fgeominit << out_linerized_el++ << " ";
for (UInt s = 0; s < spatial_dimension; ++s)
fgeominit << mid[s] << " ";
fgeominit << std::endl;;
}
}
fgeominit.close();
}
#endif
/// Check the graph
AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
"Graph to partition is not consistent");
/// Partition the mesh
SCOTCH_graphPart(&scotch_graph, nb_part, &scotch_strat, parttab);
/// Check the graph
AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
"Partitioned graph is not consistent");
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
/// save the partitioned graph
FILE *fgraph=fopen("GraphFile.grf", "w");
SCOTCH_graphSave(&scotch_graph, fgraph);
fclose(fgraph);
/// save the partition map
std::ofstream fmap;
fmap.open("MapFile.map");
fmap << vertnbr << std::endl;
for (Int i = 0; i < vertnbr; i++) fmap << i << " " << parttab[i] << std::endl;
fmap.close();
}
#endif
/// free the scotch data structures
SCOTCH_stratExit(&scotch_strat);
SCOTCH_graphFree(&scotch_graph);
SCOTCH_graphExit(&scotch_graph);
fillPartitionInformation(mesh, parttab);
delete [] parttab;
restoreConnectivity();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionScotch::reorder() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Reordering the mesh " << mesh.getID());
SCOTCH_Mesh * scotch_mesh = createMesh(mesh);
UInt nb_nodes = mesh.getNbNodes();
SCOTCH_Strat scotch_strat;
// SCOTCH_Ordering scotch_order;
SCOTCH_Num * permtab = new SCOTCH_Num[nb_nodes];
SCOTCH_Num * peritab = NULL;
SCOTCH_Num cblknbr = 0;
SCOTCH_Num * rangtab = NULL;
SCOTCH_Num * treetab = NULL;
/// Initialize the strategy structure
SCOTCH_stratInit (&scotch_strat);
SCOTCH_Graph scotch_graph;
SCOTCH_graphInit(&scotch_graph);
SCOTCH_meshGraph(scotch_mesh, &scotch_graph);
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
FILE *fgraphinit = fopen("ScotchMesh.grf", "w");
SCOTCH_graphSave(&scotch_graph,fgraphinit);
fclose(fgraphinit);
}
#endif
/// Check the graph
// AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
// "Mesh to Graph is not consistent");
SCOTCH_graphOrder(&scotch_graph, &scotch_strat,
permtab,
peritab,
&cblknbr,
rangtab,
treetab);
SCOTCH_graphExit(&scotch_graph);
SCOTCH_stratExit(&scotch_strat);
destroyMesh(scotch_mesh);
/// Renumbering
UInt spatial_dimension = mesh.getSpatialDimension();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
Mesh::type_iterator it = mesh.firstType(_all_dimensions, gt);
Mesh::type_iterator end = mesh.lastType(_all_dimensions, gt);
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type, gt);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, gt);
UInt * conn = connectivity.storage();
for (UInt el = 0; el < nb_element * nb_nodes_per_element; ++el, ++conn) {
*conn = permtab[*conn];
}
}
}
/// \todo think of a in-place way to do it
Real * new_coordinates = new Real[spatial_dimension * nb_nodes];
Real * old_coordinates = mesh.getNodes().storage();
for (UInt i = 0; i < nb_nodes; ++i) {
memcpy(new_coordinates + permtab[i] * spatial_dimension,
old_coordinates + i * spatial_dimension,
spatial_dimension * sizeof(Real));
}
memcpy(old_coordinates, new_coordinates, nb_nodes * spatial_dimension * sizeof(Real));
delete [] new_coordinates;
delete [] permtab;
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh b/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
index 963225bcf..56fd76021 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
+++ b/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
@@ -1,80 +1,81 @@
/**
* @file mesh_partition_scotch.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Aug 16 2010
- * @date last modification: Mon Jun 09 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief mesh partitioning based on libScotch
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_PARTITION_SCOTCH_HH__
#define __AKANTU_MESH_PARTITION_SCOTCH_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_partition.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class MeshPartitionScotch : public MeshPartition {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshPartitionScotch(const Mesh & mesh, UInt spatial_dimension,
const ID & id = "mesh_partition_scotch",
const MemoryID & memory_id = 0);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void partitionate(UInt nb_part,
const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
const Array<UInt> & pairs = Array<UInt>());
virtual void reorder();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
__END_AKANTU__
#endif /* __AKANTU_MESH_PARTITION_SCOTCH_HH__ */
diff --git a/src/mesh_utils/mesh_utils.cc b/src/mesh_utils/mesh_utils.cc
index 9528921d7..869d6c8ee 100644
--- a/src/mesh_utils/mesh_utils.cc
+++ b/src/mesh_utils/mesh_utils.cc
@@ -1,2204 +1,2205 @@
/**
* @file mesh_utils.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Aug 20 2010
- * @date last modification: Mon Jun 09 2014
+ * @date last modification: Sun Nov 15 2015
*
* @brief All mesh utils necessary for various tasks
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "mesh_utils.hh"
#include "aka_safe_enum.hh"
#include "fe_engine.hh"
/* -------------------------------------------------------------------------- */
#include <limits>
#include <numeric>
#include <queue>
#include <set>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
void MeshUtils::buildNode2Elements(const Mesh & mesh,
CSR<Element> & node_to_elem,
UInt spatial_dimension) {
AKANTU_DEBUG_IN();
if (spatial_dimension == _all_dimensions) spatial_dimension = mesh.getSpatialDimension();
/// count number of occurrence of each node
UInt nb_nodes = mesh.getNbNodes();
/// array for the node-element list
node_to_elem.resizeRows(nb_nodes);
node_to_elem.clearRows();
AKANTU_DEBUG_ASSERT(mesh.firstType(spatial_dimension) !=
mesh.lastType(spatial_dimension),
"Some elements must be found in right dimension to compute facets!");
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
Mesh::type_iterator first = mesh.firstType(spatial_dimension, *gt, _ek_not_defined);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, *gt, _ek_not_defined);
for (; first != last; ++first) {
ElementType type = *first;
UInt nb_element = mesh.getNbElement(type, *gt);
Array<UInt>::const_iterator< Vector<UInt> > conn_it =
mesh.getConnectivity(type, *gt).begin(Mesh::getNbNodesPerElement(type));
for (UInt el = 0; el < nb_element; ++el, ++conn_it)
for (UInt n = 0; n < conn_it->size(); ++n)
++node_to_elem.rowOffset((*conn_it)(n));
}
}
node_to_elem.countToCSR();
node_to_elem.resizeCols();
/// rearrange element to get the node-element list
Element e;
node_to_elem.beginInsertions();
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
Mesh::type_iterator first = mesh.firstType(spatial_dimension, *gt, _ek_not_defined);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, *gt, _ek_not_defined);
e.ghost_type = *gt;
for (; first != last; ++first) {
ElementType type = *first;
e.type = type;
e.kind = Mesh::getKind(type);
UInt nb_element = mesh.getNbElement(type, *gt);
Array<UInt>::const_iterator< Vector<UInt> > conn_it =
mesh.getConnectivity(type, *gt).begin(Mesh::getNbNodesPerElement(type));
for (UInt el = 0; el < nb_element; ++el, ++conn_it) {
e.element = el;
for (UInt n = 0; n < conn_it->size(); ++n)
node_to_elem.insertInRow((*conn_it)(n), e);
}
}
}
node_to_elem.endInsertions();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* This function should disappear in the future (used in mesh partitioning)
*/
void MeshUtils::buildNode2Elements(const Mesh & mesh,
CSR<UInt> & node_to_elem,
UInt spatial_dimension) {
AKANTU_DEBUG_IN();
if (spatial_dimension == _all_dimensions) spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes = mesh.getNbNodes();
const Mesh::ConnectivityTypeList & type_list = mesh.getConnectivityTypeList();
Mesh::ConnectivityTypeList::const_iterator it;
UInt nb_types = type_list.size();
UInt nb_good_types = 0;
UInt nb_nodes_per_element[nb_types];
UInt * conn_val[nb_types];
UInt nb_element[nb_types];
for(it = type_list.begin(); it != type_list.end(); ++it) {
ElementType type = *it;
if(Mesh::getSpatialDimension(type) != spatial_dimension) continue;
nb_nodes_per_element[nb_good_types] = Mesh::getNbNodesPerElement(type);
conn_val[nb_good_types] = mesh.getConnectivity(type, _not_ghost).storage();
nb_element[nb_good_types] = mesh.getConnectivity(type, _not_ghost).getSize();
nb_good_types++;
}
AKANTU_DEBUG_ASSERT(nb_good_types != 0,
"Some elements must be found in right dimension to compute facets!");
/// array for the node-element list
node_to_elem.resizeRows(nb_nodes);
node_to_elem.clearRows();
/// count number of occurrence of each node
for (UInt t = 0; t < nb_good_types; ++t) {
for (UInt el = 0; el < nb_element[t]; ++el) {
UInt el_offset = el*nb_nodes_per_element[t];
for (UInt n = 0; n < nb_nodes_per_element[t]; ++n) {
++node_to_elem.rowOffset(conn_val[t][el_offset + n]);
}
}
}
node_to_elem.countToCSR();
node_to_elem.resizeCols();
node_to_elem.beginInsertions();
/// rearrange element to get the node-element list
for (UInt t = 0, linearized_el = 0; t < nb_good_types; ++t)
for (UInt el = 0; el < nb_element[t]; ++el, ++linearized_el) {
UInt el_offset = el*nb_nodes_per_element[t];
for (UInt n = 0; n < nb_nodes_per_element[t]; ++n)
node_to_elem.insertInRow(conn_val[t][el_offset + n], linearized_el);
}
node_to_elem.endInsertions();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildNode2ElementsElementTypeMap(const Mesh & mesh,
CSR<UInt> & node_to_elem,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_elements = mesh.getConnectivity(type, ghost_type).getSize();
UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
/// array for the node-element list
node_to_elem.resizeRows(nb_nodes);
node_to_elem.clearRows();
/// count number of occurrence of each node
for (UInt el = 0; el < nb_elements; ++el) {
UInt el_offset = el*nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n)
++node_to_elem.rowOffset(conn_val[el_offset + n]);
}
/// convert the occurrence array in a csr one
node_to_elem.countToCSR();
node_to_elem.resizeCols();
node_to_elem.beginInsertions();
/// save the element index in the node-element list
for (UInt el = 0; el < nb_elements; ++el) {
UInt el_offset = el*nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
node_to_elem.insertInRow(conn_val[el_offset + n], el);
}
}
node_to_elem.endInsertions();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildFacets(Mesh & mesh){
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
mesh.getConnectivity(*it, *gt).resize(0);
// \todo inform the mesh event handler
}
}
buildFacetsDimension(mesh,
mesh,
true,
spatial_dimension);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildAllFacets(const Mesh & mesh,
Mesh & mesh_facets,
UInt to_dimension,
DistributedSynchronizer * synchronizer) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
buildAllFacets(mesh, mesh_facets, spatial_dimension, to_dimension, synchronizer);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildAllFacets(const Mesh & mesh,
Mesh & mesh_facets,
UInt from_dimension,
UInt to_dimension,
DistributedSynchronizer * synchronizer) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(mesh_facets.isMeshFacets(),
"The mesh_facets should be initialized with initMeshFacets");
const ElementTypeMapArray<UInt> * prank_to_element = NULL;
if (synchronizer) {
synchronizer->buildPrankToElement();
prank_to_element = &synchronizer->getPrankToElement();
}
/// generate facets
buildFacetsDimension(mesh,
mesh_facets,
false,
from_dimension,
prank_to_element);
/// copy nodes type
mesh_facets.nodes_type.resize(mesh.nodes_type.getSize());
mesh_facets.nodes_type.copy(mesh.nodes_type);
/// sort facets and generate subfacets
for (UInt i = from_dimension - 1; i > to_dimension; --i) {
buildFacetsDimension(mesh_facets,
mesh_facets,
false,
i,
prank_to_element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildFacetsDimension(const Mesh & mesh,
Mesh & mesh_facets,
bool boundary_only,
UInt dimension,
const ElementTypeMapArray<UInt> * prank_to_element){
AKANTU_DEBUG_IN();
// save the current parent of mesh_facets and set it temporarly to mesh since
// mesh is the one containing the elements for which mesh_facets has the subelements
// example: if the function is called with mesh = mesh_facets
const Mesh & mesh_facets_parent = mesh_facets.getMeshParent();
mesh_facets.defineMeshParent(mesh);
UInt spatial_dimension = mesh.getSpatialDimension();
const Array<Real> & mesh_facets_nodes = mesh_facets.getNodes();
const Array<Real>::const_vector_iterator mesh_facets_nodes_it =
mesh_facets_nodes.begin(spatial_dimension);
CSR<Element> node_to_elem;
buildNode2Elements(mesh, node_to_elem, dimension);
Array<UInt> counter;
std::vector<Element> connected_elements;
// init the SubelementToElement data to improve performance
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Mesh::type_iterator first = mesh.firstType(dimension, ghost_type);
Mesh::type_iterator last = mesh.lastType(dimension, ghost_type);
for(; first != last; ++first) {
ElementType type = *first;
mesh_facets.getSubelementToElementPointer(type, ghost_type);
Vector<ElementType> facet_types = mesh.getAllFacetTypes(type);
for (UInt ft = 0; ft < facet_types.size(); ++ft) {
ElementType facet_type = facet_types(ft);
mesh_facets.getElementToSubelementPointer(facet_type, ghost_type);
mesh_facets.getConnectivityPointer(facet_type, ghost_type);
}
}
}
Element current_element;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
GhostType facet_ghost_type = ghost_type;
current_element.ghost_type = ghost_type;
Mesh::type_iterator first = mesh.firstType(dimension, ghost_type);
Mesh::type_iterator last = mesh.lastType(dimension, ghost_type);
for(; first != last; ++first) {
ElementType type = *first;
Vector<ElementType> facet_types = mesh.getAllFacetTypes(type);
current_element.type = type;
for (UInt ft = 0; ft < facet_types.size(); ++ft) {
ElementType facet_type = facet_types(ft);
UInt nb_element = mesh.getNbElement(type, ghost_type);
Array< std::vector<Element> > * element_to_subelement =
&mesh_facets.getElementToSubelement(facet_type, ghost_type);
Array<UInt> * connectivity_facets = &mesh_facets.getConnectivity(facet_type, ghost_type);
UInt nb_facet_per_element = mesh.getNbFacetsPerElement(type, ft);
const Array<UInt> & element_connectivity = mesh.getConnectivity(type, ghost_type);
const Matrix<UInt> facet_local_connectivity = mesh.getFacetLocalConnectivity(type, ft);
UInt nb_nodes_per_facet = connectivity_facets->getNbComponent();
Vector<UInt> facet(nb_nodes_per_facet);
for (UInt el = 0; el < nb_element; ++el) {
current_element.element = el;
for (UInt f = 0; f < nb_facet_per_element; ++f) {
for (UInt n = 0; n < nb_nodes_per_facet; ++n)
facet(n) = element_connectivity(el, facet_local_connectivity(f, n));
UInt first_node_nb_elements = node_to_elem.getNbCols(facet(0));
counter.resize(first_node_nb_elements);
counter.clear();
//loop over the other nodes to search intersecting elements,
//which are the elements that share another node with the
//starting element after first_node
CSR<Element>::iterator first_node_elements = node_to_elem.begin(facet(0));
CSR<Element>::iterator first_node_elements_end = node_to_elem.end(facet(0));
UInt local_el = 0;
for (; first_node_elements != first_node_elements_end;
++first_node_elements, ++local_el) {
for (UInt n = 1; n < nb_nodes_per_facet; ++n) {
CSR<Element>::iterator node_elements_begin = node_to_elem.begin(facet(n));
CSR<Element>::iterator node_elements_end = node_to_elem.end (facet(n));
counter(local_el) += std::count(node_elements_begin,
node_elements_end,
*first_node_elements);
}
}
// counting the number of elements connected to the facets and
// taking the minimum element number, because the facet should
// be inserted just once
UInt nb_element_connected_to_facet = 0;
Element minimum_el = ElementNull;
connected_elements.clear();
for (UInt el_f = 0; el_f < first_node_nb_elements; el_f++) {
Element real_el = node_to_elem(facet(0), el_f);
if (counter(el_f) == nb_nodes_per_facet - 1) {
++nb_element_connected_to_facet;
minimum_el = std::min(minimum_el, real_el);
connected_elements.push_back(real_el);
}
}
if (minimum_el == current_element) {
bool full_ghost_facet = false;
UInt n = 0;
while (n < nb_nodes_per_facet && mesh.isPureGhostNode(facet(n))) ++n;
if (n == nb_nodes_per_facet) full_ghost_facet = true;
if (!full_ghost_facet) {
if (!boundary_only || (boundary_only && nb_element_connected_to_facet == 1)) {
std::vector<Element> elements;
// build elements_on_facets: linearized_el must come first
// in order to store the facet in the correct direction
// and avoid to invert the sign in the normal computation
elements.push_back(current_element);
/// boundary facet
if (nb_element_connected_to_facet == 1)
elements.push_back(ElementNull);
/// internal facet
else if (nb_element_connected_to_facet == 2) {
elements.push_back(connected_elements[1]);
/// check if facet is in between ghost and normal
/// elements: if it's the case, the facet is either
/// ghost or not ghost. The criterion to decide this
/// is arbitrary. It was chosen to check the processor
/// id (prank) of the two neighboring elements. If
/// prank of the ghost element is lower than prank of
/// the normal one, the facet is not ghost, otherwise
/// it's ghost
GhostType gt[2] = { _not_ghost, _not_ghost };
for (UInt el = 0; el < connected_elements.size(); ++el)
gt[el] = connected_elements[el].ghost_type;
if (gt[0] + gt[1] == 1) {
if (prank_to_element) {
UInt prank[2];
for (UInt el = 0; el < 2; ++el) {
UInt current_el = connected_elements[el].element;
ElementType current_type = connected_elements[el].type;
GhostType current_gt = connected_elements[el].ghost_type;
const Array<UInt> & prank_to_el
= (*prank_to_element)(current_type, current_gt);
prank[el] = prank_to_el(current_el);
}
bool ghost_one = (gt[0] != _ghost);
if (prank[ghost_one] > prank[!ghost_one])
facet_ghost_type = _not_ghost;
else
facet_ghost_type = _ghost;
connectivity_facets = &mesh_facets.getConnectivity(facet_type, facet_ghost_type);
element_to_subelement = &mesh_facets.getElementToSubelement(facet_type, facet_ghost_type);
}
}
}
/// facet of facet
else {
for (UInt i = 1; i < nb_element_connected_to_facet; ++i) {
elements.push_back(connected_elements[i]);
}
}
element_to_subelement->push_back(elements);
connectivity_facets->push_back(facet);
/// current facet index
UInt current_facet = connectivity_facets->getSize() - 1;
/// loop on every element connected to current facet and
/// insert current facet in the first free spot of the
/// subelement_to_element vector
for (UInt elem = 0; elem < elements.size(); ++elem) {
Element loc_el = elements[elem];
if (loc_el.type != _not_defined) {
Array<Element> & subelement_to_element =
mesh_facets.getSubelementToElement(loc_el.type, loc_el.ghost_type);
UInt nb_facet_per_loc_element = subelement_to_element.getNbComponent();
for (UInt f_in = 0; f_in < nb_facet_per_loc_element; ++f_in) {
if (subelement_to_element(loc_el.element, f_in).type == _not_defined) {
subelement_to_element(loc_el.element, f_in).type = facet_type;
subelement_to_element(loc_el.element, f_in).element = current_facet;
subelement_to_element(loc_el.element, f_in).ghost_type = facet_ghost_type;
break;
}
}
}
}
/// reset connectivity in case a facet was found in
/// between ghost and normal elements
if (facet_ghost_type != ghost_type) {
facet_ghost_type = ghost_type;
connectivity_facets = mesh_facets.getConnectivityPointer(facet_type, facet_ghost_type);
element_to_subelement = mesh_facets.getElementToSubelementPointer(facet_type, facet_ghost_type);
}
}
}
}
}
}
}
}
}
// restore the parent of mesh_facet
mesh_facets.defineMeshParent(mesh_facets_parent);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::renumberMeshNodes(Mesh & mesh,
UInt * local_connectivities,
UInt nb_local_element,
UInt nb_ghost_element,
ElementType type,
Array<UInt> & old_nodes_numbers) {
AKANTU_DEBUG_IN();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
std::map<UInt, UInt> renumbering_map;
for (UInt i = 0; i < old_nodes_numbers.getSize(); ++i) {
renumbering_map[old_nodes_numbers(i)] = i;
}
/// renumber the nodes
renumberNodesInConnectivity(local_connectivities,
(nb_local_element + nb_ghost_element)*nb_nodes_per_element,
renumbering_map);
std::map<UInt, UInt>::iterator it = renumbering_map.begin();
std::map<UInt, UInt>::iterator end = renumbering_map.end();
old_nodes_numbers.resize(renumbering_map.size());
for (;it != end; ++it) {
old_nodes_numbers(it->second) = it->first;
}
renumbering_map.clear();
/// copy the renumbered connectivity to the right place
Array<UInt> * local_conn = mesh.getConnectivityPointer(type);
local_conn->resize(nb_local_element);
memcpy(local_conn->storage(),
local_connectivities,
nb_local_element * nb_nodes_per_element * sizeof(UInt));
Array<UInt> * ghost_conn = mesh.getConnectivityPointer(type, _ghost);
ghost_conn->resize(nb_ghost_element);
memcpy(ghost_conn->storage(),
local_connectivities + nb_local_element * nb_nodes_per_element,
nb_ghost_element * nb_nodes_per_element * sizeof(UInt));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::renumberNodesInConnectivity(UInt * list_nodes,
UInt nb_nodes,
std::map<UInt, UInt> & renumbering_map) {
AKANTU_DEBUG_IN();
UInt * connectivity = list_nodes;
UInt new_node_num = renumbering_map.size();
for (UInt n = 0; n < nb_nodes; ++n, ++connectivity) {
UInt & node = *connectivity;
std::map<UInt, UInt>::iterator it = renumbering_map.find(node);
if(it == renumbering_map.end()) {
UInt old_node = node;
renumbering_map[old_node] = new_node_num;
node = new_node_num;
++new_node_num;
} else {
node = it->second;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::purifyMesh(Mesh & mesh) {
AKANTU_DEBUG_IN();
std::map<UInt, UInt> renumbering_map;
RemovedNodesEvent remove_nodes(mesh);
Array<UInt> & nodes_removed = remove_nodes.getList();
for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type = (GhostType) gt;
Mesh::type_iterator it = mesh.firstType(_all_dimensions, ghost_type, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType(_all_dimensions, ghost_type, _ek_not_defined);
for(; it != end; ++it) {
ElementType type(*it);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity_vect = mesh.getConnectivity(type, ghost_type);
UInt nb_element(connectivity_vect.getSize());
UInt * connectivity = connectivity_vect.storage();
renumberNodesInConnectivity (connectivity, nb_element*nb_nodes_per_element, renumbering_map);
}
}
Array<UInt> & new_numbering = remove_nodes.getNewNumbering();
std::fill(new_numbering.begin(), new_numbering.end(), UInt(-1));
std::map<UInt, UInt>::iterator it = renumbering_map.begin();
std::map<UInt, UInt>::iterator end = renumbering_map.end();
for (; it != end; ++it) {
new_numbering(it->first) = it->second;
}
for (UInt i = 0; i < new_numbering.getSize(); ++i) {
if(new_numbering(i) == UInt(-1))
nodes_removed.push_back(i);
}
mesh.sendEvent(remove_nodes);
AKANTU_DEBUG_OUT();
}
#if defined(AKANTU_COHESIVE_ELEMENT)
/* -------------------------------------------------------------------------- */
UInt MeshUtils::insertCohesiveElements(Mesh & mesh,
Mesh & mesh_facets,
const ElementTypeMapArray<bool> & facet_insertion,
Array<UInt> & doubled_nodes,
Array<Element> & new_elements,
bool only_double_facets) {
UInt spatial_dimension = mesh.getSpatialDimension();
UInt elements_to_insert = updateFacetToDouble(mesh_facets, facet_insertion);
if (elements_to_insert > 0) {
if (spatial_dimension == 1) {
doublePointFacet(mesh, mesh_facets, doubled_nodes);
}
else {
doubleFacet(mesh, mesh_facets, spatial_dimension - 1,
doubled_nodes, true);
findSubfacetToDouble<false>(mesh, mesh_facets);
if (spatial_dimension == 2) {
doubleSubfacet<2>(mesh, mesh_facets, doubled_nodes);
}
else if (spatial_dimension == 3) {
doubleFacet(mesh, mesh_facets, 1, doubled_nodes, false);
findSubfacetToDouble<true>(mesh, mesh_facets);
doubleSubfacet<3>(mesh, mesh_facets, doubled_nodes);
}
}
if (!only_double_facets)
updateCohesiveData(mesh, mesh_facets, new_elements);
}
return elements_to_insert;
}
#endif
/* -------------------------------------------------------------------------- */
void MeshUtils::doubleNodes(Mesh & mesh,
const std::vector<UInt> & old_nodes,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
Array<Real> & position = mesh.getNodes();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt old_nb_nodes = position.getSize();
UInt new_nb_nodes = old_nb_nodes + old_nodes.size();
UInt old_nb_doubled_nodes = doubled_nodes.getSize();
UInt new_nb_doubled_nodes = old_nb_doubled_nodes + old_nodes.size();
position.resize(new_nb_nodes);
doubled_nodes.resize(new_nb_doubled_nodes);
Array<Real>::iterator<Vector<Real> > position_begin
= position.begin(spatial_dimension);
for (UInt n = 0; n < old_nodes.size(); ++n) {
UInt new_node = old_nb_nodes + n;
/// store doubled nodes
doubled_nodes(old_nb_doubled_nodes + n, 0) = old_nodes[n];
doubled_nodes(old_nb_doubled_nodes + n, 1) = new_node;
/// update position
std::copy(position_begin + old_nodes[n],
position_begin + old_nodes[n] + 1,
position_begin + new_node);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::doubleFacet(Mesh & mesh,
Mesh & mesh_facets,
UInt facet_dimension,
Array<UInt> & doubled_nodes,
bool facet_mode) {
AKANTU_DEBUG_IN();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(facet_dimension, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(facet_dimension, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
if (nb_facet_to_double == 0) continue;
ElementType type_subfacet = Mesh::getFacetType(type_facet);
const UInt nb_subfacet_per_facet = Mesh::getNbFacetsPerElement(type_facet);
GhostType gt_subfacet = _casper;
Array<std::vector<Element> > * f_to_subfacet = NULL;
Array<Element> & subfacet_to_facet
= mesh_facets.getSubelementToElement(type_facet, gt_facet);
Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
UInt nb_nodes_per_facet = conn_facet.getNbComponent();
UInt old_nb_facet = conn_facet.getSize();
UInt new_nb_facet = old_nb_facet + nb_facet_to_double;
conn_facet.resize(new_nb_facet);
subfacet_to_facet.resize(new_nb_facet);
UInt new_facet = old_nb_facet - 1;
Element new_facet_el(type_facet, 0, gt_facet);
Array<Element>::iterator<Vector<Element> > subfacet_to_facet_begin
= subfacet_to_facet.begin(nb_subfacet_per_facet);
Array<UInt>::iterator<Vector<UInt> > conn_facet_begin
= conn_facet.begin(nb_nodes_per_facet);
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
++new_facet;
/// adding a new facet by copying original one
/// copy connectivity in new facet
std::copy(conn_facet_begin + old_facet,
conn_facet_begin + old_facet + 1,
conn_facet_begin + new_facet);
/// update subfacet_to_facet
std::copy(subfacet_to_facet_begin + old_facet,
subfacet_to_facet_begin + old_facet + 1,
subfacet_to_facet_begin + new_facet);
new_facet_el.element = new_facet;
/// loop on every subfacet
for (UInt sf = 0; sf < nb_subfacet_per_facet; ++sf) {
Element & subfacet = subfacet_to_facet(old_facet, sf);
if (subfacet == ElementNull) continue;
if (gt_subfacet != subfacet.ghost_type) {
gt_subfacet = subfacet.ghost_type;
f_to_subfacet = & mesh_facets.getElementToSubelement(type_subfacet,
subfacet.ghost_type);
}
/// update facet_to_subfacet array
(*f_to_subfacet)(subfacet.element).push_back(new_facet_el);
}
}
/// update facet_to_subfacet and _segment_3 facets if any
if (!facet_mode) {
updateSubfacetToFacet(mesh_facets, type_facet, gt_facet, true);
updateFacetToSubfacet(mesh_facets, type_facet, gt_facet, true);
updateQuadraticSegments<true>(mesh, mesh_facets, type_facet,
gt_facet, doubled_nodes);
}
else
updateQuadraticSegments<false>(mesh, mesh_facets, type_facet,
gt_facet, doubled_nodes);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
UInt MeshUtils::updateFacetToDouble(Mesh & mesh_facets,
const ElementTypeMapArray<bool> & facet_insertion) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh_facets.getSpatialDimension();
UInt nb_facets_to_double = 0.;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
const Array<bool> & f_insertion = facet_insertion(type_facet, gt_facet);
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
ElementType el_type = _not_defined;
GhostType el_gt = _casper;
UInt nb_facet_per_element = 0;
Element old_facet_el(type_facet, 0, gt_facet);
Array<Element> * facet_to_element = NULL;
for (UInt f = 0; f < f_insertion.getSize(); ++f) {
if (f_insertion(f) == false) continue;
++nb_facets_to_double;
if (element_to_facet(f)[1].type == _not_defined
#if defined(AKANTU_COHESIVE_ELEMENT)
|| element_to_facet(f)[1].kind == _ek_cohesive
#endif
) {
AKANTU_DEBUG_WARNING("attempt to double a facet on the boundary");
continue;
}
f_to_double.push_back(f);
UInt new_facet =
mesh_facets.getNbElement(type_facet, gt_facet) + f_to_double.getSize() - 1;
old_facet_el.element = f;
/// update facet_to_element vector
Element & elem_to_update = element_to_facet(f)[1];
UInt el = elem_to_update.element;
if (elem_to_update.ghost_type != el_gt || elem_to_update.type != el_type) {
el_type = elem_to_update.type;
el_gt = elem_to_update.ghost_type;
facet_to_element = & mesh_facets.getSubelementToElement(el_type, el_gt);
nb_facet_per_element = facet_to_element->getNbComponent();
}
Element * f_update
= std::find(facet_to_element->storage() + el * nb_facet_per_element,
facet_to_element->storage() + el * nb_facet_per_element
+ nb_facet_per_element,
old_facet_el);
AKANTU_DEBUG_ASSERT(facet_to_element->storage() + el * nb_facet_per_element !=
facet_to_element->storage() + el * nb_facet_per_element
+ nb_facet_per_element,
"Facet not found");
f_update->element = new_facet;
/// update elements connected to facet
std::vector<Element> first_facet_list = element_to_facet(f);
element_to_facet.push_back(first_facet_list);
/// set new and original facets as boundary facets
element_to_facet(new_facet)[0] = element_to_facet(new_facet)[1];
element_to_facet(f)[1] = ElementNull;
element_to_facet(new_facet)[1] = ElementNull;
}
}
}
AKANTU_DEBUG_OUT();
return nb_facets_to_double;
}
/* -------------------------------------------------------------------------- */
void MeshUtils::resetFacetToDouble(Mesh & mesh_facets) {
AKANTU_DEBUG_IN();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
Mesh::type_iterator it = mesh_facets.firstType(_all_dimensions, gt);
Mesh::type_iterator end = mesh_facets.lastType(_all_dimensions, gt);
for(; it != end; ++it) {
ElementType type = *it;
mesh_facets.getDataPointer<UInt>("facet_to_double", type, gt, 1, false);
mesh_facets.getDataPointer<std::vector<Element> >
("facets_to_subfacet_double", type, gt, 1, false);
mesh_facets.getDataPointer<std::vector<Element> >
("elements_to_subfacet_double", type, gt, 1, false);
mesh_facets.getDataPointer<std::vector<Element> >
("subfacets_to_subsubfacet_double", type, gt, 1, false);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool subsubfacet_mode>
void MeshUtils::findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh_facets.getSpatialDimension();
if (spatial_dimension == 1) return;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
if (nb_facet_to_double == 0) continue;
ElementType type_subfacet = Mesh::getFacetType(type_facet);
GhostType gt_subfacet = _casper;
ElementType type_subsubfacet = Mesh::getFacetType(type_subfacet);
GhostType gt_subsubfacet = _casper;
Array<UInt> * conn_subfacet = NULL;
Array<UInt> * sf_to_double = NULL;
Array<std::vector<Element> > * sf_to_subfacet_double = NULL;
Array<std::vector<Element> > * f_to_subfacet_double = NULL;
Array<std::vector<Element> > * el_to_subfacet_double = NULL;
UInt nb_subfacet = Mesh::getNbFacetsPerElement(type_facet);
UInt nb_subsubfacet;
UInt nb_nodes_per_sf_el;
if (subsubfacet_mode) {
nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subsubfacet);
nb_subsubfacet = Mesh::getNbFacetsPerElement(type_subfacet);
}
else
nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subfacet);
Array<Element> & subfacet_to_facet
= mesh_facets.getSubelementToElement(type_facet, gt_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
Array<Element> * subsubfacet_to_subfacet = NULL;
UInt old_nb_facet = subfacet_to_facet.getSize() - nb_facet_to_double;
Element current_facet(type_facet, 0, gt_facet);
std::vector<Element> element_list;
std::vector<Element> facet_list;
std::vector<Element> * subfacet_list;
if (subsubfacet_mode)
subfacet_list = new std::vector<Element>;
/// map to filter subfacets
Array< std::vector<Element> > * facet_to_subfacet = NULL;
/// this is used to make sure that both new and old facets are
/// checked
UInt facets[2];
/// loop on every facet
for (UInt f_index = 0; f_index < 2; ++f_index) {
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
facets[bool(f_index)] = f_to_double(facet);
facets[!bool(f_index)] = old_nb_facet + facet;
UInt old_facet = facets[0];
UInt new_facet = facets[1];
Element & starting_element = element_to_facet(new_facet)[0];
current_facet.element = old_facet;
/// loop on every subfacet
for (UInt sf = 0; sf < nb_subfacet; ++sf) {
Element & subfacet = subfacet_to_facet(old_facet, sf);
if (subfacet == ElementNull) continue;
if (gt_subfacet != subfacet.ghost_type) {
gt_subfacet = subfacet.ghost_type;
if (subsubfacet_mode) {
subsubfacet_to_subfacet
= & mesh_facets.getSubelementToElement(type_subfacet,
gt_subfacet);
}
else {
conn_subfacet = & mesh_facets.getConnectivity(type_subfacet,
gt_subfacet);
sf_to_double = & mesh_facets.getData<UInt>("facet_to_double",
type_subfacet,
gt_subfacet);
f_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subfacet,
gt_subfacet);
el_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("elements_to_subfacet_double",
type_subfacet,
gt_subfacet);
facet_to_subfacet
= & mesh_facets.getElementToSubelement(type_subfacet,
gt_subfacet);
}
}
if (subsubfacet_mode) {
/// loop on every subsubfacet
for (UInt ssf = 0; ssf < nb_subsubfacet; ++ssf) {
Element & subsubfacet
= (*subsubfacet_to_subfacet)(subfacet.element, ssf);
if (subsubfacet == ElementNull) continue;
if (gt_subsubfacet != subsubfacet.ghost_type) {
gt_subsubfacet = subsubfacet.ghost_type;
conn_subfacet = & mesh_facets.getConnectivity(type_subsubfacet,
gt_subsubfacet);
sf_to_double = & mesh_facets.getData<UInt>("facet_to_double",
type_subsubfacet,
gt_subsubfacet);
sf_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("subfacets_to_subsubfacet_double",
type_subsubfacet,
gt_subsubfacet);
f_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subsubfacet,
gt_subsubfacet);
el_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("elements_to_subfacet_double",
type_subsubfacet,
gt_subsubfacet);
facet_to_subfacet
= & mesh_facets.getElementToSubelement(type_subsubfacet,
gt_subsubfacet);
}
UInt global_ssf = subsubfacet.element;
Vector<UInt> subsubfacet_connectivity(conn_subfacet->storage()
+ global_ssf
* nb_nodes_per_sf_el,
nb_nodes_per_sf_el);
/// check if subsubfacet is to be doubled
if (findElementsAroundSubfacet<true>(mesh, mesh_facets,
starting_element, current_facet,
subsubfacet_connectivity,
element_list,
facet_list,
subfacet_list) == false &&
removeElementsInVector(*subfacet_list,
(*facet_to_subfacet)(global_ssf)) == false) {
sf_to_double->push_back(global_ssf);
sf_to_subfacet_double->push_back(*subfacet_list);
f_to_subfacet_double->push_back(facet_list);
el_to_subfacet_double->push_back(element_list);
}
}
}
else {
const UInt global_sf = subfacet.element;
Vector<UInt> subfacet_connectivity(conn_subfacet->storage()
+ global_sf
* nb_nodes_per_sf_el,
nb_nodes_per_sf_el);
/// check if subfacet is to be doubled
if (findElementsAroundSubfacet<false>(mesh, mesh_facets,
starting_element, current_facet,
subfacet_connectivity,
element_list,
facet_list) == false &&
removeElementsInVector(facet_list,
(*facet_to_subfacet)(global_sf)) == false) {
sf_to_double->push_back(global_sf);
f_to_subfacet_double->push_back(facet_list);
el_to_subfacet_double->push_back(element_list);
}
}
}
}
}
if (subsubfacet_mode)
delete subfacet_list;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_COHESIVE_ELEMENT)
void MeshUtils::updateCohesiveData(Mesh & mesh,
Mesh & mesh_facets,
Array<Element> & new_elements) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
bool third_dimension = spatial_dimension == 3;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
if (nb_facet_to_double == 0) continue;
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
Array<Element> * facet_to_coh_element
= mesh_facets.getSubelementToElementPointer(type_cohesive, gt_facet);
Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
Array<UInt> * conn_cohesive = mesh.getConnectivityPointer(type_cohesive,
gt_facet);
UInt nb_nodes_per_facet = Mesh::getNbNodesPerElement(type_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
UInt old_nb_cohesive_elements = conn_cohesive->getSize();
UInt new_nb_cohesive_elements = conn_cohesive->getSize() + nb_facet_to_double;
UInt old_nb_facet = element_to_facet.getSize() - nb_facet_to_double;
facet_to_coh_element->resize(new_nb_cohesive_elements);
conn_cohesive->resize(new_nb_cohesive_elements);
UInt new_elements_old_size = new_elements.getSize();
new_elements.resize(new_elements_old_size + nb_facet_to_double);
Element c_element(type_cohesive, 0, gt_facet, _ek_cohesive);
Element f_element(type_facet, 0, gt_facet);
UInt facets[2];
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
/// (in 3D cohesive elements connectivity is inverted)
facets[third_dimension] = f_to_double(facet);
facets[!third_dimension] = old_nb_facet + facet;
UInt cohesive_element = old_nb_cohesive_elements + facet;
/// store doubled facets
f_element.element = facets[0];
(*facet_to_coh_element)(cohesive_element, 0) = f_element;
f_element.element = facets[1];
(*facet_to_coh_element)(cohesive_element, 1) = f_element;
/// modify cohesive elements' connectivity
for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
(*conn_cohesive)(cohesive_element, n) = conn_facet(facets[0], n);
(*conn_cohesive)(cohesive_element, n + nb_nodes_per_facet)
= conn_facet(facets[1], n);
}
/// update element_to_facet vectors
c_element.element = cohesive_element;
element_to_facet(facets[0])[1] = c_element;
element_to_facet(facets[1])[1] = c_element;
/// add cohesive element to the element event list
new_elements(new_elements_old_size + facet) = c_element;
}
}
}
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
void MeshUtils::doublePointFacet(Mesh & mesh,
Mesh & mesh_facets,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
if (spatial_dimension != 1) return;
Array<Real> & position = mesh.getNodes();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
const Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
UInt old_nb_facet = element_to_facet.getSize() - nb_facet_to_double;
UInt new_nb_facet = element_to_facet.getSize();
UInt old_nb_nodes = position.getSize();
UInt new_nb_nodes = old_nb_nodes + nb_facet_to_double;
position.resize(new_nb_nodes);
conn_facet.resize(new_nb_facet);
UInt old_nb_doubled_nodes = doubled_nodes.getSize();
doubled_nodes.resize(old_nb_doubled_nodes + nb_facet_to_double);
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
UInt new_facet = old_nb_facet + facet;
ElementType type = element_to_facet(new_facet)[0].type;
UInt el = element_to_facet(new_facet)[0].element;
GhostType gt = element_to_facet(new_facet)[0].ghost_type;
UInt old_node = conn_facet(old_facet);
UInt new_node = old_nb_nodes + facet;
/// update position
position(new_node) = position(old_node);
conn_facet(new_facet) = new_node;
Array<UInt> & conn_segment = mesh.getConnectivity(type, gt);
UInt nb_nodes_per_segment = conn_segment.getNbComponent();
/// update facet connectivity
UInt i;
for (i = 0; conn_segment(el, i) != old_node
&& i <= nb_nodes_per_segment; ++i);
conn_segment(el, i) = new_node;
doubled_nodes(old_nb_doubled_nodes + facet, 0) = old_node;
doubled_nodes(old_nb_doubled_nodes + facet, 1) = new_node;
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool third_dim_segments>
void MeshUtils::updateQuadraticSegments(Mesh & mesh,
Mesh & mesh_facets,
ElementType type_facet,
GhostType gt_facet,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
if (type_facet != _segment_3) return;
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
UInt old_nb_facet
= mesh_facets.getNbElement(type_facet, gt_facet) - nb_facet_to_double;
Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet,
gt_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
/// this ones matter only for segments in 3D
Array< std::vector<Element> > * el_to_subfacet_double = NULL;
Array< std::vector<Element> > * f_to_subfacet_double = NULL;
if (third_dim_segments) {
el_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("elements_to_subfacet_double",
type_facet,
gt_facet);
f_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_facet,
gt_facet);
}
std::vector<UInt> middle_nodes;
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
UInt node = conn_facet(old_facet, 2);
if (!mesh.isPureGhostNode(node)) middle_nodes.push_back(node);
}
UInt n = doubled_nodes.getSize();
doubleNodes(mesh, middle_nodes, doubled_nodes);
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
UInt old_node = conn_facet(old_facet, 2);
if (mesh.isPureGhostNode(old_node)) continue;
UInt new_node = doubled_nodes(n, 1);
UInt new_facet = old_nb_facet + facet;
conn_facet(new_facet, 2) = new_node;
if (third_dim_segments) {
updateElementalConnectivity(mesh_facets,
old_node, new_node,
element_to_facet(new_facet));
updateElementalConnectivity(mesh,
old_node, new_node,
(*el_to_subfacet_double)(facet),
&(*f_to_subfacet_double)(facet));
}
else {
updateElementalConnectivity(mesh,
old_node, new_node,
element_to_facet(new_facet));
}
++n;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::updateSubfacetToFacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet,
bool facet_mode) {
AKANTU_DEBUG_IN();
Array<UInt> & sf_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_subfacet,
gt_subfacet);
UInt nb_subfacet_to_double = sf_to_double.getSize();
/// update subfacet_to_facet vector
ElementType type_facet = _not_defined;
GhostType gt_facet = _casper;
Array<Element> * subfacet_to_facet = NULL;
UInt nb_subfacet_per_facet = 0;
UInt old_nb_subfacet
= mesh_facets.getNbElement(type_subfacet, gt_subfacet) - nb_subfacet_to_double;
Array<std::vector<Element> > * facet_list = NULL;
if (facet_mode)
facet_list = & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subfacet,
gt_subfacet);
else
facet_list = & mesh_facets.getData<std::vector<Element> >("subfacets_to_subsubfacet_double",
type_subfacet,
gt_subfacet);
Element old_subfacet_el(type_subfacet, 0, gt_subfacet);
Element new_subfacet_el(type_subfacet, 0, gt_subfacet);
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
old_subfacet_el.element = sf_to_double(sf);
new_subfacet_el.element = old_nb_subfacet + sf;
for (UInt f = 0; f < (*facet_list)(sf).size(); ++f) {
Element & facet = (*facet_list)(sf)[f];
if (facet.type != type_facet || facet.ghost_type != gt_facet) {
type_facet = facet.type;
gt_facet = facet.ghost_type;
subfacet_to_facet = & mesh_facets.getSubelementToElement(type_facet,
gt_facet);
nb_subfacet_per_facet = subfacet_to_facet->getNbComponent();
}
Element * sf_update
= std::find(subfacet_to_facet->storage()
+ facet.element * nb_subfacet_per_facet,
subfacet_to_facet->storage()
+ facet.element * nb_subfacet_per_facet + nb_subfacet_per_facet,
old_subfacet_el);
AKANTU_DEBUG_ASSERT(subfacet_to_facet->storage()
+ facet.element * nb_subfacet_per_facet !=
subfacet_to_facet->storage()
+ facet.element * nb_subfacet_per_facet + nb_subfacet_per_facet,
"Subfacet not found");
*sf_update = new_subfacet_el;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::updateFacetToSubfacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet,
bool facet_mode) {
AKANTU_DEBUG_IN();
Array<UInt> & sf_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_subfacet,
gt_subfacet);
UInt nb_subfacet_to_double = sf_to_double.getSize();
Array< std::vector<Element> > & facet_to_subfacet
= mesh_facets.getElementToSubelement(type_subfacet, gt_subfacet);
Array< std::vector<Element> > * facet_to_subfacet_double = NULL;
if (facet_mode) {
facet_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subfacet,
gt_subfacet);
}
else {
facet_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("subfacets_to_subsubfacet_double",
type_subfacet,
gt_subfacet);
}
UInt old_nb_subfacet = facet_to_subfacet.getSize();
facet_to_subfacet.resize(old_nb_subfacet + nb_subfacet_to_double);
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf)
facet_to_subfacet(old_nb_subfacet + sf) = (*facet_to_subfacet_double)(sf);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MeshUtils::doubleSubfacet(Mesh & mesh,
Mesh & mesh_facets,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
if (spatial_dimension == 1) return;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_subfacet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(0, gt_subfacet);
Mesh::type_iterator end = mesh_facets.lastType(0, gt_subfacet);
for(; it != end; ++it) {
ElementType type_subfacet = *it;
Array<UInt> & sf_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_subfacet,
gt_subfacet);
UInt nb_subfacet_to_double = sf_to_double.getSize();
if (nb_subfacet_to_double == 0) continue;
AKANTU_DEBUG_ASSERT(type_subfacet == _point_1,
"Only _point_1 subfacet doubling is supported at the moment");
Array<UInt> & conn_subfacet = mesh_facets.getConnectivity(type_subfacet,
gt_subfacet);
UInt old_nb_subfacet = conn_subfacet.getSize();
UInt new_nb_subfacet = old_nb_subfacet + nb_subfacet_to_double;
conn_subfacet.resize(new_nb_subfacet);
std::vector<UInt> nodes_to_double;
UInt old_nb_doubled_nodes = doubled_nodes.getSize();
/// double nodes
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
UInt old_subfacet = sf_to_double(sf);
nodes_to_double.push_back(conn_subfacet(old_subfacet));
}
doubleNodes(mesh, nodes_to_double, doubled_nodes);
/// add new nodes in connectivity
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
UInt new_subfacet = old_nb_subfacet + sf;
UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
conn_subfacet(new_subfacet) = new_node;
}
/// update facet and element connectivity
Array<std::vector<Element> > & f_to_subfacet_double =
mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subfacet,
gt_subfacet);
Array<std::vector<Element> > & el_to_subfacet_double =
mesh_facets.getData<std::vector<Element> >("elements_to_subfacet_double",
type_subfacet,
gt_subfacet);
Array<std::vector<Element> > * sf_to_subfacet_double = NULL;
if (spatial_dimension == 3)
sf_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("subfacets_to_subsubfacet_double",
type_subfacet,
gt_subfacet);
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
UInt old_node = doubled_nodes(old_nb_doubled_nodes + sf, 0);
UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
updateElementalConnectivity(mesh,
old_node, new_node,
el_to_subfacet_double(sf),
&f_to_subfacet_double(sf));
updateElementalConnectivity(mesh_facets,
old_node, new_node,
f_to_subfacet_double(sf));
if (spatial_dimension == 3)
updateElementalConnectivity(mesh_facets,
old_node, new_node,
(*sf_to_subfacet_double)(sf));
}
if (spatial_dimension == 2) {
updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, true);
updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, true);
}
else if (spatial_dimension == 3) {
updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, false);
updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, false);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::flipFacets(Mesh & mesh_facets,
const ElementTypeMapArray<UInt> & global_connectivity,
GhostType gt_facet) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh_facets.getSpatialDimension();
/// get global connectivity for local mesh
ElementTypeMapArray<UInt> global_connectivity_tmp;
mesh_facets.initElementTypeMapArray(global_connectivity_tmp, 1,
spatial_dimension - 1, gt_facet,
true, _ek_regular, true);
mesh_facets.getGlobalConnectivity(global_connectivity_tmp,
spatial_dimension - 1, gt_facet);
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
/// loop on every facet
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & connectivity = mesh_facets.getConnectivity(type_facet, gt_facet);
const Array<UInt> & g_connectivity = global_connectivity(type_facet, gt_facet);
Array<std::vector<Element> > & el_to_f =
mesh_facets.getElementToSubelement(type_facet, gt_facet);
Array<Element> & subfacet_to_facet =
mesh_facets.getSubelementToElement(type_facet, gt_facet);
UInt nb_subfacet_per_facet = subfacet_to_facet.getNbComponent();
UInt nb_nodes_per_facet = connectivity.getNbComponent();
UInt nb_facet = connectivity.getSize();
UInt nb_nodes_per_P1_facet
= Mesh::getNbNodesPerElement(Mesh::getP1ElementType(type_facet));
Array<UInt> & global_conn_tmp = global_connectivity_tmp(type_facet, gt_facet);
Array<UInt>::iterator<Vector<UInt> > conn_it =
connectivity.begin(nb_nodes_per_facet);
Array<UInt>::iterator<Vector<UInt> > gconn_tmp_it =
global_conn_tmp.begin(nb_nodes_per_facet);
Array<UInt>::const_iterator<Vector<UInt> > conn_glob_it =
g_connectivity.begin(nb_nodes_per_facet);
Array<Element>::iterator<Vector<Element> > subf_to_f =
subfacet_to_facet.begin(nb_subfacet_per_facet);
UInt * conn_tmp_pointer = new UInt[nb_nodes_per_facet];
Vector<UInt> conn_tmp(conn_tmp_pointer, nb_nodes_per_facet);
Element el_tmp;
Element * subf_tmp_pointer = new Element[nb_subfacet_per_facet];
Vector<Element> subf_tmp(subf_tmp_pointer, nb_subfacet_per_facet);
for (UInt f = 0; f < nb_facet; ++f, ++conn_it, ++gconn_tmp_it,
++subf_to_f, ++conn_glob_it) {
Vector<UInt> & gconn_tmp = *gconn_tmp_it;
const Vector<UInt> & conn_glob = *conn_glob_it;
Vector<UInt> & conn_local = *conn_it;
/// skip facet if connectivities are the same
if (gconn_tmp == conn_glob) continue;
/// re-arrange connectivity
conn_tmp = conn_local;
UInt * begin = conn_glob.storage();
UInt * end = conn_glob.storage() + nb_nodes_per_facet;
for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
UInt * new_node = std::find(begin, end, gconn_tmp(n));
AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
UInt new_position = new_node - begin;
conn_local(new_position) = conn_tmp(n);
}
/// if 3D, check if facets are just rotated
if (spatial_dimension == 3) {
/// find first node
UInt * new_node = std::find(begin, end, gconn_tmp(0));
AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
UInt new_position = new_node - begin;
UInt n = 1;
/// count how many nodes in the received connectivity follow
/// the same order of those in the local connectivity
for (; n < nb_nodes_per_P1_facet &&
gconn_tmp(n) == conn_glob((new_position + n) % nb_nodes_per_P1_facet);
++n);
/// skip the facet inversion if facet is just rotated
if (n == nb_nodes_per_P1_facet) continue;
}
/// update data to invert facet
el_tmp = el_to_f(f)[0];
el_to_f(f)[0] = el_to_f(f)[1];
el_to_f(f)[1] = el_tmp;
subf_tmp = (*subf_to_f);
(*subf_to_f)(0) = subf_tmp(1);
(*subf_to_f)(1) = subf_tmp(0);
}
delete [] subf_tmp_pointer;
delete [] conn_tmp_pointer;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::fillElementToSubElementsData(Mesh & mesh) {
AKANTU_DEBUG_IN();
if(mesh.getNbElement(mesh.getSpatialDimension() - 1) == 0) {
AKANTU_DEBUG_INFO("There are not facets, add them in the mesh file or call the buildFacet method.");
return;
}
UInt spatial_dimension = mesh.getSpatialDimension();
ElementTypeMapArray<Real> barycenters("barycenter_tmp", mesh.getID());
mesh.initElementTypeMapArray(barycenters,
spatial_dimension,
_all_dimensions);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end();
++gt) {
Mesh::type_iterator it = mesh.firstType(_all_dimensions, *gt);
Mesh::type_iterator end = mesh.lastType(_all_dimensions, *gt);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it, *gt);
Array<Real> & barycenters_arr = barycenters(*it, *gt);
barycenters_arr.resize(nb_element);
Array<Real>::vector_iterator bary = barycenters_arr.begin(spatial_dimension);
Array<Real>::vector_iterator bary_end = barycenters_arr.end(spatial_dimension);
for (UInt el = 0; bary != bary_end; ++bary, ++el) {
mesh.getBarycenter(el, *it, bary->storage(), *gt);
}
}
}
for(Int sp(spatial_dimension); sp >= 1; --sp) {
if(mesh.getNbElement(sp) == 0) continue;
for (ghost_type_t::iterator git = ghost_type_t::begin(); git != ghost_type_t::end(); ++git) {
Mesh::type_iterator tit = mesh.firstType(sp, *git);
Mesh::type_iterator tend = mesh.lastType(sp, *git);
for (;tit != tend; ++tit) {
mesh.getSubelementToElementPointer(*tit, *git)->resize(mesh.getNbElement(*tit, *git));
mesh.getSubelementToElement(*tit, *git).clear();
}
tit = mesh.firstType(sp - 1, *git);
tend = mesh.lastType(sp - 1, *git);
for (;tit != tend; ++tit) {
mesh.getElementToSubelementPointer(*tit, *git)->resize(mesh.getNbElement(*tit, *git));
mesh.getElementToSubelement(*tit, *git).clear();
}
}
CSR<Element> nodes_to_elements;
buildNode2Elements(mesh, nodes_to_elements, sp);
Element facet_element;
for (ghost_type_t::iterator git = ghost_type_t::begin(); git != ghost_type_t::end(); ++git) {
Mesh::type_iterator tit = mesh.firstType(sp - 1, *git);
Mesh::type_iterator tend = mesh.lastType(sp - 1, *git);
facet_element.ghost_type = *git;
for (;tit != tend; ++tit) {
facet_element.type = *tit;
Array< std::vector<Element> > & element_to_subelement = mesh.getElementToSubelement(*tit, *git);
const Array<UInt> & connectivity = mesh.getConnectivity(*tit, *git);
Array<UInt>::const_iterator< Vector<UInt> > fit = connectivity.begin(mesh.getNbNodesPerElement(*tit));
Array<UInt>::const_iterator< Vector<UInt> > fend = connectivity.end(mesh.getNbNodesPerElement(*tit));
UInt fid = 0;
for (;fit != fend; ++fit, ++fid) {
const Vector<UInt> & facet = *fit;
facet_element.element = fid;
std::map<Element, UInt> element_seen_counter;
UInt nb_nodes_per_facet = mesh.getNbNodesPerElement(Mesh::getP1ElementType(*tit));
for (UInt n(0); n < nb_nodes_per_facet; ++n) {
CSR<Element>::iterator eit = nodes_to_elements.begin(facet(n));
CSR<Element>::iterator eend = nodes_to_elements.end(facet(n));
for(;eit != eend; ++eit) {
Element & elem = *eit;
std::map<Element, UInt>::iterator cit = element_seen_counter.find(elem);
if(cit != element_seen_counter.end()) {
cit->second++;
} else {
element_seen_counter[elem] = 1;
}
}
}
std::vector<Element> connected_elements;
std::map<Element, UInt>::iterator cit = element_seen_counter.begin();
std::map<Element, UInt>::iterator cend = element_seen_counter.end();
for(;cit != cend; ++cit) {
if(cit->second == nb_nodes_per_facet) connected_elements.push_back(cit->first);
}
std::vector<Element>::iterator ceit = connected_elements.begin();
std::vector<Element>::iterator ceend = connected_elements.end();
for(;ceit != ceend; ++ceit)
element_to_subelement(fid).push_back(*ceit);
for (UInt ce = 0; ce < connected_elements.size(); ++ce) {
Element & elem = connected_elements[ce];
Array<Element> & subelement_to_element =
*(mesh.getSubelementToElementPointer(elem.type,
elem.ghost_type));
UInt f(0);
for(; f < mesh.getNbFacetsPerElement(elem.type) &&
subelement_to_element(elem.element, f) != ElementNull; ++f);
AKANTU_DEBUG_ASSERT(f < mesh.getNbFacetsPerElement(elem.type), "The element " << elem << " seems to have too many facets!! (" << f << " < " << mesh.getNbFacetsPerElement(elem.type) << ")");
subelement_to_element(elem.element, f) = facet_element;
}
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool third_dim_points>
bool MeshUtils::findElementsAroundSubfacet(const Mesh & mesh,
const Mesh & mesh_facets,
const Element & starting_element,
const Element & end_facet,
const Vector<UInt> & subfacet_connectivity,
std::vector<Element> & elem_list,
std::vector<Element> & facet_list,
std::vector<Element> * subfacet_list) {
AKANTU_DEBUG_IN();
/// preallocated stuff before starting
bool facet_matched = false;
elem_list.clear();
facet_list.clear();
if (third_dim_points)
subfacet_list->clear();
elem_list.push_back(starting_element);
const Array<UInt> * facet_connectivity = NULL;
const Array<UInt> * sf_connectivity = NULL;
const Array<Element> * facet_to_element = NULL;
const Array<Element> * subfacet_to_facet = NULL;
ElementType current_type = _not_defined;
GhostType current_ghost_type = _casper;
ElementType current_facet_type = _not_defined;
GhostType current_facet_ghost_type = _casper;
ElementType current_subfacet_type = _not_defined;
GhostType current_subfacet_ghost_type = _casper;
const Array< std::vector<Element> > * element_to_facet = NULL;
const Element * opposing_el = NULL;
std::queue<Element> elements_to_check;
elements_to_check.push(starting_element);
/// keep going until there are elements to check
while (!elements_to_check.empty()) {
/// check current element
Element & current_el = elements_to_check.front();
if (current_el.type != current_type ||
current_el.ghost_type != current_ghost_type) {
current_type = current_el.type;
current_ghost_type = current_el.ghost_type;
facet_to_element = & mesh_facets.getSubelementToElement(current_type,
current_ghost_type);
}
/// loop over each facet of the element
for (UInt f = 0; f < facet_to_element->getNbComponent(); ++f) {
const Element & current_facet = (*facet_to_element)(current_el.element, f);
if (current_facet == ElementNull) continue;
if (current_facet_type != current_facet.type ||
current_facet_ghost_type != current_facet.ghost_type) {
current_facet_type = current_facet.type;
current_facet_ghost_type = current_facet.ghost_type;
element_to_facet =
& mesh_facets.getElementToSubelement(current_facet_type,
current_facet_ghost_type);
facet_connectivity = & mesh_facets.getConnectivity(current_facet_type,
current_facet_ghost_type);
if (third_dim_points)
subfacet_to_facet =
& mesh_facets.getSubelementToElement(current_facet_type,
current_facet_ghost_type);
}
/// check if end facet is reached
if (current_facet == end_facet)
facet_matched = true;
/// add this facet if not already passed
if (std::find(facet_list.begin(),
facet_list.end(),
current_facet) == facet_list.end() &&
hasElement(*facet_connectivity, current_facet, subfacet_connectivity)) {
facet_list.push_back(current_facet);
if (third_dim_points) {
/// check subfacets
for (UInt sf = 0; sf < subfacet_to_facet->getNbComponent(); ++sf) {
const Element & current_subfacet
= (*subfacet_to_facet)(current_facet.element, sf);
if (current_subfacet == ElementNull) continue;
if (current_subfacet_type != current_subfacet.type ||
current_subfacet_ghost_type != current_subfacet.ghost_type) {
current_subfacet_type = current_subfacet.type;
current_subfacet_ghost_type = current_subfacet.ghost_type;
sf_connectivity
= & mesh_facets.getConnectivity(current_subfacet_type,
current_subfacet_ghost_type);
}
if (std::find(subfacet_list->begin(),
subfacet_list->end(),
current_subfacet) == subfacet_list->end() &&
hasElement(*sf_connectivity, current_subfacet, subfacet_connectivity))
subfacet_list->push_back(current_subfacet);
}
}
}
else
continue;
/// consider opposing element
if ( (*element_to_facet)(current_facet.element)[0] == current_el)
opposing_el = & (*element_to_facet)(current_facet.element)[1];
else
opposing_el = & (*element_to_facet)(current_facet.element)[0];
/// skip null elements since they are on a boundary
if (*opposing_el == ElementNull) continue;
/// skip this element if already added
if ( std::find(elem_list.begin(),
elem_list.end(),
*opposing_el) != elem_list.end() ) continue;
/// only regular elements have to be checked
if (opposing_el->kind == _ek_regular)
elements_to_check.push(*opposing_el);
elem_list.push_back(*opposing_el);
#ifndef AKANTU_NDEBUG
const Array<UInt> & conn_elem = mesh.getConnectivity(opposing_el->type,
opposing_el->ghost_type);
AKANTU_DEBUG_ASSERT(hasElement(conn_elem, *opposing_el, subfacet_connectivity),
"Subfacet doesn't belong to this element");
#endif
}
/// erased checked element from the list
elements_to_check.pop();
}
AKANTU_DEBUG_OUT();
return facet_matched;
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildSegmentToNodeType(const Mesh & mesh,
Mesh & mesh_facets,
DistributedSynchronizer * synchronizer) {
buildAllFacets(mesh, mesh_facets, 1, synchronizer);
UInt spatial_dimension = mesh.getSpatialDimension();
const ElementTypeMapArray<UInt> & element_to_rank = synchronizer->getPrankToElement();
Int local_rank = StaticCommunicator::getStaticCommunicator().whoAmI();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end();
++gt) {
GhostType ghost_type = *gt;
Mesh::type_iterator it = mesh_facets.firstType(1, ghost_type);
Mesh::type_iterator end = mesh_facets.lastType(1, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_segments = mesh_facets.getNbElement(type, ghost_type);
// allocate the data
Array<Int> & segment_to_nodetype =
*(mesh_facets.getDataPointer<Int>("segment_to_nodetype", type, ghost_type));
std::set<Element> connected_elements;
const Array< std::vector<Element> > & segment_to_2Delement
= mesh_facets.getElementToSubelement(type, ghost_type);
// loop over segments
for (UInt s = 0; s < nb_segments; ++s) {
// determine the elements connected to the segment
connected_elements.clear();
const std::vector<Element> & twoD_elements = segment_to_2Delement(s);
if (spatial_dimension == 2) {
// if 2D just take the elements connected to the segments
connected_elements.insert(twoD_elements.begin(), twoD_elements.end());
} else if (spatial_dimension == 3) {
// if 3D a second loop is needed to get to the 3D elements
std::vector<Element>::const_iterator facet = twoD_elements.begin();
for (; facet != twoD_elements.end(); ++facet) {
const std::vector<Element> & threeD_elements
= mesh_facets.getElementToSubelement(facet->type, facet->ghost_type)(facet->element);
connected_elements.insert(threeD_elements.begin(), threeD_elements.end());
}
}
// get the minimum processor rank associated to the connected
// elements and verify if ghost and not ghost elements are
// found
Int minimum_rank = std::numeric_limits<Int>::max();
// two booleans saying if not ghost and ghost elements are found in the loop
bool ghost_found[2];
ghost_found[0] = false; ghost_found[1] = false;
std::set<Element>::iterator connected_elements_it = connected_elements.begin();
for (; connected_elements_it != connected_elements.end(); ++connected_elements_it) {
if (*connected_elements_it == ElementNull) continue;
ghost_found[connected_elements_it->ghost_type] = true;
const Array<UInt> & el_to_rank_array = element_to_rank(connected_elements_it->type,
connected_elements_it->ghost_type);
minimum_rank = std::min(minimum_rank, Int(el_to_rank_array(connected_elements_it->element)));
}
// if no ghost elements are found the segment is local
if (!ghost_found[1]) segment_to_nodetype(s) = -1;
// if no not ghost elements are found the segment is pure ghost
else if (!ghost_found[0]) segment_to_nodetype(s) = -3;
// if the minimum rank is equal to the local rank, the segment is master
else if (local_rank == minimum_rank) segment_to_nodetype(s) = -2;
// if the minimum rank is less than the local rank, the segment is slave
else if (local_rank > minimum_rank) segment_to_nodetype(s) = minimum_rank;
else AKANTU_DEBUG_ERROR("The local rank cannot be smaller than the minimum rank if both ghost and not ghost elements are found");
}
}
}
}
/* -------------------------------------------------------------------------- */
UInt MeshUtils::updateLocalMasterGlobalConnectivity(Mesh & mesh, UInt local_nb_new_nodes) {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int rank = comm.whoAmI();
Int nb_proc = comm.getNbProc();
if (nb_proc == 1) return local_nb_new_nodes;
/// resize global ids array
Array<UInt> & nodes_global_ids = mesh.getGlobalNodesIds();
UInt old_nb_nodes = mesh.getNbNodes() - local_nb_new_nodes;
nodes_global_ids.resize(mesh.getNbNodes());
/// compute the number of global nodes based on the number of old nodes
Vector<UInt> old_local_master_nodes(nb_proc);
for (UInt n = 0; n < old_nb_nodes; ++n)
if (mesh.isLocalOrMasterNode(n)) ++old_local_master_nodes(rank);
comm.allGather(old_local_master_nodes.storage(), 1);
UInt old_global_nodes = std::accumulate(old_local_master_nodes.storage(),
old_local_master_nodes.storage() + nb_proc,
0);
/// compute amount of local or master doubled nodes
Vector<UInt> local_master_nodes(nb_proc);
for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n)
if (mesh.isLocalOrMasterNode(n)) ++local_master_nodes(rank);
comm.allGather(local_master_nodes.storage(), 1);
/// update global number of nodes
UInt total_nb_new_nodes = std::accumulate(local_master_nodes.storage(),
local_master_nodes.storage() + nb_proc,
0);
if (total_nb_new_nodes == 0) return 0;
/// set global ids of local and master nodes
UInt starting_index = std::accumulate(local_master_nodes.storage(),
local_master_nodes.storage() + rank,
old_global_nodes);
for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n) {
if (mesh.isLocalOrMasterNode(n)) {
nodes_global_ids(n) = starting_index;
++starting_index;
}
}
mesh.nb_global_nodes = old_global_nodes + total_nb_new_nodes;
return total_nb_new_nodes;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
// LocalWords: ElementType
diff --git a/src/mesh_utils/mesh_utils.hh b/src/mesh_utils/mesh_utils.hh
index 8c216a95b..88b5a8385 100644
--- a/src/mesh_utils/mesh_utils.hh
+++ b/src/mesh_utils/mesh_utils.hh
@@ -1,278 +1,279 @@
/**
* @file mesh_utils.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri Aug 20 2010
- * @date last modification: Mon Jun 23 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Oct 02 2015
*
* @brief All mesh utils necessary for various tasks
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "mesh.hh"
#include "aka_csr.hh"
#include "distributed_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#include <vector>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_UTILS_HH__
#define __AKANTU_MESH_UTILS_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class MeshUtils {
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// build a CSR<UInt> that contains for each node the linearized number of
/// the connected elements of a given spatial dimension
static void buildNode2Elements(const Mesh & mesh,
CSR<UInt> & node_to_elem,
UInt spatial_dimension = _all_dimensions);
/// build a CSR<Element> that contains for each node the list of connected
/// elements of a given spatial dimension
static void buildNode2Elements(const Mesh & mesh,
CSR<Element> & node_to_elem,
UInt spatial_dimension = _all_dimensions);
/// build a CSR<UInt> that contains for each node the number of
/// the connected elements of a given ElementType
static void buildNode2ElementsElementTypeMap(const Mesh & mesh,
CSR<UInt> & node_to_elem,
const ElementType & type,
const GhostType & ghost_type = _not_ghost);
/// build the facets elements on the boundaries of a mesh
static void buildFacets(Mesh & mesh);
/// build all the facets elements: boundary and internals and store them in
/// the mesh_facets for element of dimension from_dimension to to_dimension
static void buildAllFacets(const Mesh & mesh,
Mesh & mesh_facets,
UInt from_dimension,
UInt to_dimension,
DistributedSynchronizer * synchronizer = NULL);
/// build all the facets elements: boundary and internals and store them in
/// the mesh_facets
static void buildAllFacets(const Mesh & mesh,
Mesh & mesh_facets,
UInt to_dimension = 0,
DistributedSynchronizer * synchronizer = NULL);
/// build facets for a given spatial dimension
static void buildFacetsDimension(const Mesh & mesh,
Mesh & mesh_facets,
bool boundary_only,
UInt dimension,
const ElementTypeMapArray<UInt> * prank_to_element = NULL);
/// take the local_connectivity array as the array of local and ghost
/// connectivity, renumber the nodes and set the connectivity of the mesh
static void renumberMeshNodes(Mesh & mesh,
UInt * local_connectivities,
UInt nb_local_element,
UInt nb_ghost_element,
ElementType type,
Array<UInt> & old_nodes);
/// compute pbc pair for a given direction
static void computePBCMap(const Mesh & mymesh, const UInt dir,
std::map<UInt,UInt> & pbc_pair);
/// compute pbc pair for a surface pair
static void computePBCMap(const Mesh & mymesh,
const std::pair<Surface, Surface> & surface_pair,
std::map<UInt,UInt> & pbc_pair);
/// remove not connected nodes /!\ this functions renumbers the nodes.
static void purifyMesh(Mesh & mesh);
#if defined(AKANTU_COHESIVE_ELEMENT)
/// function to insert cohesive elements on the selected facets
/// @return number of facets that have been doubled
static UInt insertCohesiveElements(Mesh & mesh,
Mesh & mesh_facets,
const ElementTypeMapArray<bool> & facet_insertion,
Array<UInt> & doubled_nodes,
Array<Element> & new_elements,
bool only_double_facets);
#endif
/// fill the subelement to element and the elements to subelements data
static void fillElementToSubElementsData(Mesh & mesh);
/// flip facets based on global connectivity
static void flipFacets(Mesh & mesh_facets,
const ElementTypeMapArray<UInt> & global_connectivity,
GhostType gt_facet);
/// provide list of elements around a node and check if a given
/// facet is reached
template <bool third_dim_points>
static bool findElementsAroundSubfacet(const Mesh & mesh,
const Mesh & mesh_facets,
const Element & starting_element,
const Element & end_facet,
const Vector<UInt> & subfacet_connectivity,
std::vector<Element> & elem_list,
std::vector<Element> & facet_list,
std::vector<Element> * subfacet_list = NULL);
/// function to check if a node belongs to a given element
static inline bool hasElement(const Array<UInt> & connectivity,
const Element & el,
const Vector<UInt> & nodes);
/// reset facet_to_double arrays in the Mesh
static void resetFacetToDouble(Mesh & mesh_facets);
/// associate a node type to each segment in the mesh
static void buildSegmentToNodeType(const Mesh & mesh,
Mesh & mesh_facets,
DistributedSynchronizer * synchronizer);
/// update local and master global connectivity when new nodes are added
static UInt updateLocalMasterGlobalConnectivity(Mesh & mesh, UInt old_nb_nodes);
private:
/// match pairs that are on the associated pbc's
static void matchPBCPairs(const Mesh & mymesh,
const UInt dir,
Array<UInt> & selected_left,
Array<UInt> & selected_right,
std::map<UInt,UInt> & pbc_pair);
/// function used by all the renumbering functions
static void renumberNodesInConnectivity(UInt * list_nodes,
UInt nb_nodes,
std::map<UInt, UInt> & renumbering_map);
/// update facet_to_subfacet
static void updateFacetToSubfacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet,
bool facet_mode);
/// update subfacet_to_facet
static void updateSubfacetToFacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet,
bool facet_mode);
/// function to double a given facet and update the list of doubled
/// nodes
static void doubleFacet(Mesh & mesh,
Mesh & mesh_facets,
UInt facet_dimension,
Array<UInt> & doubled_nodes,
bool facet_mode);
/// function to double a subfacet given start and end index for
/// local facet_to_subfacet vector, and update the list of doubled
/// nodes
template <UInt spatial_dimension>
static void doubleSubfacet(Mesh & mesh,
Mesh & mesh_facets,
Array<UInt> & doubled_nodes);
/// double a node
static void doubleNodes(Mesh & mesh,
const std::vector<UInt> & old_nodes,
Array<UInt> & doubled_nodes);
/// fill facet_to_double array in the mesh
/// returns the number of facets to be doubled
static UInt updateFacetToDouble(Mesh & mesh_facets,
const ElementTypeMapArray<bool> & facet_insertion);
/// find subfacets to be doubled
template <bool subsubfacet_mode>
static void findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets);
/// double facets (points) in 1D
static void doublePointFacet(Mesh & mesh,
Mesh & mesh_facets,
Array<UInt> & doubled_nodes);
#if defined(AKANTU_COHESIVE_ELEMENT)
/// update cohesive element data
static void updateCohesiveData(Mesh & mesh,
Mesh & mesh_facets,
Array<Element> & new_elements);
#endif
/// update elemental connectivity after doubling a node
inline static void updateElementalConnectivity(Mesh & mesh,
UInt old_node,
UInt new_node,
const std::vector<Element> & element_list,
const std::vector<Element> * facet_list = NULL);
/// double middle nodes if facets are _segment_3
template <bool third_dim_segments>
static void updateQuadraticSegments(Mesh & mesh,
Mesh & mesh_facets,
ElementType type_facet,
GhostType gt_facet,
Array<UInt> & doubled_nodes);
/// remove elements on a vector
inline static bool removeElementsInVector(const std::vector<Element> & elem_to_remove,
std::vector<Element> & elem_list);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "mesh_utils_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MESH_UTILS_HH__ */
diff --git a/src/mesh_utils/mesh_utils_inline_impl.cc b/src/mesh_utils/mesh_utils_inline_impl.cc
index d7b3a2e9a..ce6a6a608 100644
--- a/src/mesh_utils/mesh_utils_inline_impl.cc
+++ b/src/mesh_utils/mesh_utils_inline_impl.cc
@@ -1,160 +1,162 @@
/**
* @file mesh_utils_inline_impl.cc
*
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Aug 20 2010
- * @date last modification: Mon Jun 09 2014
+ * @date last modification: Fri Mar 20 2015
*
* @brief Mesh utils inline functions
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline bool MeshUtils::hasElement(const Array<UInt> & connectivity,
const Element & el,
const Vector<UInt> & nodes) {
UInt nb_nodes_per_element = connectivity.getNbComponent();
const Vector<UInt> el_nodes(connectivity.storage()
+ el.element * nb_nodes_per_element,
nb_nodes_per_element);
UInt * el_nodes_end = el_nodes.storage() + nb_nodes_per_element;
UInt n = 0;
while (n < nodes.size() &&
std::find(el_nodes.storage(), el_nodes_end, nodes[n]) != el_nodes_end) ++n;
return (n == nodes.size());
}
/* -------------------------------------------------------------------------- */
inline void MeshUtils::updateElementalConnectivity(Mesh & mesh,
UInt old_node,
UInt new_node,
const std::vector<Element> & element_list,
const std::vector<Element> * facet_list) {
AKANTU_DEBUG_IN();
ElementType el_type = _not_defined;
GhostType gt_type = _casper;
Array<UInt> * conn_elem = NULL;
#if defined(AKANTU_COHESIVE_ELEMENT)
const Array<Element> * cohesive_facets = NULL;
#endif
UInt nb_nodes_per_element = 0;
UInt * n_update = NULL;
for (UInt el = 0; el < element_list.size(); ++el) {
const Element & elem = element_list[el];
if (elem.type == _not_defined) continue;
if (elem.type != el_type || elem.ghost_type != gt_type) {
el_type = elem.type;
gt_type = elem.ghost_type;
conn_elem = & mesh.getConnectivity(el_type, gt_type);
nb_nodes_per_element = conn_elem->getNbComponent();
#if defined(AKANTU_COHESIVE_ELEMENT)
if (elem.kind == _ek_cohesive)
cohesive_facets = & mesh.getMeshFacets().getSubelementToElement(el_type, gt_type);
#endif
}
#if defined(AKANTU_COHESIVE_ELEMENT)
if (elem.kind == _ek_cohesive) {
AKANTU_DEBUG_ASSERT(facet_list != NULL,
"Provide a facet list in order to update cohesive elements");
/// loop over cohesive element's facets
for (UInt f = 0, n = 0; f < 2; ++f, n += nb_nodes_per_element / 2) {
const Element & facet = (*cohesive_facets)(elem.element, f);
/// skip facets if not present in the list
if (std::find(facet_list->begin(), facet_list->end(), facet)
== facet_list->end()) continue;
n_update
= std::find(conn_elem->storage() + elem.element * nb_nodes_per_element + n,
conn_elem->storage() + elem.element * nb_nodes_per_element + n
+ nb_nodes_per_element / 2,
old_node);
AKANTU_DEBUG_ASSERT(n_update != conn_elem->storage()
+ elem.element * nb_nodes_per_element + n
+ nb_nodes_per_element / 2,
"Node not found in current element");
/// update connectivity
*n_update = new_node;
}
}
else {
#endif
n_update
= std::find(conn_elem->storage() + elem.element * nb_nodes_per_element,
conn_elem->storage() + elem.element * nb_nodes_per_element
+ nb_nodes_per_element,
old_node);
AKANTU_DEBUG_ASSERT(n_update != conn_elem->storage()
+ elem.element * nb_nodes_per_element
+ nb_nodes_per_element,
"Node not found in current element");
/// update connectivity
*n_update = new_node;
#if defined(AKANTU_COHESIVE_ELEMENT)
}
#endif
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline bool MeshUtils::removeElementsInVector(const std::vector<Element> & elem_to_remove,
std::vector<Element> & elem_list) {
if (elem_list.size() <= elem_to_remove.size())
return true;
std::vector<Element>::const_iterator el_it = elem_to_remove.begin();
std::vector<Element>::const_iterator el_last = elem_to_remove.end();
std::vector<Element>::iterator el_del;
UInt deletions = 0;
for (; el_it != el_last; ++el_it) {
el_del = std::find(elem_list.begin(), elem_list.end(), *el_it);
if (el_del != elem_list.end()) {
elem_list.erase(el_del);
++deletions;
}
}
AKANTU_DEBUG_ASSERT(deletions == 0 || deletions == elem_to_remove.size(),
"Not all elements have been erased");
return deletions == 0;
}
diff --git a/src/mesh_utils/mesh_utils_pbc.cc b/src/mesh_utils/mesh_utils_pbc.cc
index a32f8318a..592361bc4 100644
--- a/src/mesh_utils/mesh_utils_pbc.cc
+++ b/src/mesh_utils/mesh_utils_pbc.cc
@@ -1,295 +1,296 @@
/**
* @file mesh_utils_pbc.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Wed Feb 09 2011
- * @date last modification: Fri Aug 01 2014
+ * @date last modification: Tue Sep 15 2015
*
* @brief periodic boundary condition connectivity tweak
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <map>
/* -------------------------------------------------------------------------- */
#include "mesh_utils.hh"
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/// class that sorts a set of nodes of same coordinates in 'dir' direction
class CoordinatesComparison {
public:
CoordinatesComparison (const UInt dimension,
const UInt dirx, const UInt diry,
Real normalization,
Real tolerance,
Real * coords):
dim(dimension),dir_x(dirx),dir_y(diry),normalization(normalization),
tolerance(tolerance),coordinates(coords){}
// answers the question whether n2 is larger or equal to n1
bool operator() (UInt n1, UInt n2){
Real p1_x = coordinates[dim*n1+dir_x];
Real p2_x = coordinates[dim*n2+dir_x];
Real diff_x = p1_x - p2_x;
if (dim == 2 || std::abs(diff_x)/normalization > tolerance)
return diff_x > 0.0 ? false : true;
else if (dim > 2){
Real p1_y = coordinates[dim*n1+dir_y];
Real p2_y = coordinates[dim*n2+dir_y];
Real diff_y = p1_y - p2_y;
return diff_y > 0 ? false : true;
}
return true;
}
private:
UInt dim;
UInt dir_x;
UInt dir_y;
Real normalization;
Real tolerance;
Real * coordinates;
};
/* -------------------------------------------------------------------------- */
void MeshUtils::computePBCMap(const Mesh & mymesh,
const UInt dir,
std::map<UInt,UInt> & pbc_pair){
Array<UInt> selected_left;
Array<UInt> selected_right;
Real * coords = mymesh.nodes->storage();
const UInt nb_nodes = mymesh.nodes->getSize();
const UInt dim = mymesh.getSpatialDimension();
if (dim <= dir) return;
AKANTU_DEBUG_INFO("min " << mymesh.lower_bounds[dir]);
AKANTU_DEBUG_INFO("max " << mymesh.upper_bounds[dir]);
for (UInt i = 0; i < nb_nodes; ++i) {
AKANTU_DEBUG_TRACE("treating " << coords[dim*i+dir]);
if(Math::are_float_equal(coords[dim*i+dir], mymesh.lower_bounds[dir])){
AKANTU_DEBUG_TRACE("pushing node " << i << " on the left side");
selected_left.push_back(i);
}
else if(Math::are_float_equal(coords[dim*i+dir], mymesh.upper_bounds[dir])){
selected_right.push_back(i);
AKANTU_DEBUG_TRACE("pushing node " << i << " on the right side");
}
}
AKANTU_DEBUG_INFO("found " << selected_left.getSize() << " and " << selected_right.getSize()
<< " nodes at each boundary for direction " << dir);
// match pairs
MeshUtils::matchPBCPairs(mymesh, dir, selected_left, selected_right, pbc_pair);
}
/* -------------------------------------------------------------------------- */
void MeshUtils::computePBCMap(const Mesh & mymesh,
const SurfacePair & surface_pair,
std::map<UInt,UInt> & pbc_pair) {
Array<UInt> selected_first;
Array<UInt> selected_second;
// find nodes on surfaces
const ElementGroup & first_surf = mymesh.getElementGroup(surface_pair.first);
const ElementGroup & second_surf = mymesh.getElementGroup(surface_pair.second);
// if this surface pair is not on this proc
if (first_surf.getNbNodes() == 0 || second_surf.getNbNodes() == 0) {
AKANTU_DEBUG_WARNING("computePBCMap has at least one surface without any nodes. I will ignore it.");
return;
}
// copy nodes from element group
selected_first.copy(first_surf.getNodeGroup().getNodes());
selected_second.copy(second_surf.getNodeGroup().getNodes());
// coordinates
const Array<Real> & coords = mymesh.getNodes();
const UInt dim = mymesh.getSpatialDimension();
// variables to find min and max of surfaces
Real first_max[3], first_min[3];
Real second_max[3], second_min[3];
for (UInt i=0; i<dim; ++i) {
first_min[i] = std::numeric_limits<Real>::max();
second_min[i] = std::numeric_limits<Real>::max();
first_max[i] = -std::numeric_limits<Real>::max();
second_max[i] = -std::numeric_limits<Real>::max();
}
// find min and max of surface nodes
for (Array<UInt>::scalar_iterator it = selected_first.begin();
it != selected_first.end();
++it) {
for (UInt i=0; i<dim; ++i) {
if (first_min[i] > coords(*it,i)) first_min[i] = coords(*it,i);
if (first_max[i] < coords(*it,i)) first_max[i] = coords(*it,i);
}
}
for (Array<UInt>::scalar_iterator it = selected_second.begin();
it != selected_second.end();
++it) {
for (UInt i=0; i<dim; ++i) {
if (second_min[i] > coords(*it,i)) second_min[i] = coords(*it,i);
if (second_max[i] < coords(*it,i)) second_max[i] = coords(*it,i);
}
}
// find direction of pbc
Int first_dir = -1;
#ifndef AKANTU_NDEBUG
Int second_dir = -2;
#endif
for (UInt i=0; i<dim; ++i) {
if (Math::are_float_equal(first_min[i], first_max[i])) {
first_dir = i;
}
#ifndef AKANTU_NDEBUG
if (Math::are_float_equal(second_min[i], second_max[i])) {
second_dir = i;
}
#endif
}
AKANTU_DEBUG_ASSERT(first_dir == second_dir, "Surface pair has not same direction. Surface "
<< surface_pair.first << " dir=" << first_dir << " ; Surface "
<< surface_pair.second << " dir=" << second_dir);
UInt dir = first_dir;
// match pairs
if (first_min[dir] < second_min[dir])
MeshUtils::matchPBCPairs(mymesh, dir, selected_first, selected_second, pbc_pair);
else
MeshUtils::matchPBCPairs(mymesh, dir, selected_second, selected_first, pbc_pair);
}
/* -------------------------------------------------------------------------- */
void MeshUtils::matchPBCPairs(const Mesh & mymesh,
const UInt dir,
Array<UInt> & selected_left,
Array<UInt> & selected_right,
std::map<UInt,UInt> & pbc_pair) {
// tolerance is that large because most meshers generate points coordinates
// with single precision only (it is the case of GMSH for instance)
Real tolerance = 1e-7;
Real * coords = mymesh.nodes->storage();
const UInt dim = mymesh.getSpatialDimension();
Real normalization = mymesh.upper_bounds[dir]-mymesh.lower_bounds[dir];
AKANTU_DEBUG_ASSERT(std::abs(normalization) > Math::getTolerance(),
"In matchPBCPairs: The normalization is zero. "
<< "Did you compute the bounding box of the mesh?");
UInt dir_x = UInt(-1) ,dir_y = UInt(-1);
if (dim == 3){
if (dir == 0){
dir_x = 1;dir_y = 2;
}
else if (dir == 1){
dir_x = 0;dir_y = 2;
}
else if (dir == 2){
dir_x = 0;dir_y = 1;
}
}
else if (dim == 2){
if (dir == 0){
dir_x = 1;
}
else if (dir == 1){
dir_x = 0;
}
}
CoordinatesComparison compare_nodes(dim,dir_x,dir_y,normalization,tolerance,coords);
std::sort(selected_left.begin(),selected_left.end(),compare_nodes);
std::sort(selected_right.begin(),selected_right.end(),compare_nodes);
Array<UInt>::scalar_iterator it_left = selected_left.begin();
Array<UInt>::scalar_iterator end_left = selected_left.end();
Array<UInt>::scalar_iterator it_right = selected_right.begin();
Array<UInt>::scalar_iterator end_right = selected_right.end();
while ((it_left != end_left) && (it_right != end_right) ){
UInt i1 = *it_left;
UInt i2 = *it_right;
AKANTU_DEBUG_TRACE("do I pair? " << i1 << "("
<< coords[dim*i1] << "," << coords[dim*i1+1] << ","
<< coords[dim*i1+2]
<< ") with"
<< i2 << "("
<< coords[dim*i2] << "," << coords[dim*i2+1] << ","
<< coords[dim*i2+2]
<< ") in direction " << dir);
Real dx = 0.0;
Real dy = 0.0;
if (dim >= 2) dx = coords[dim*i1 + dir_x] - coords[dim*i2 + dir_x];
if (dim == 3) dy = coords[dim*i1 + dir_y] - coords[dim*i2 + dir_y];
if (fabs(dx*dx+dy*dy)/normalization < tolerance) {
//then i match these pairs
if (pbc_pair.count(i2)){
i2 = pbc_pair[i2];
}
pbc_pair[i1] = i2;
AKANTU_DEBUG_TRACE("pairing " << i1 << "("
<< coords[dim*i1] << "," << coords[dim*i1+1] << ","
<< coords[dim*i1+2]
<< ") with"
<< i2 << "("
<< coords[dim*i2] << "," << coords[dim*i2+1] << ","
<< coords[dim*i2+2]
<< ") in direction " << dir);
++it_left;
++it_right;
} else if (compare_nodes(i1, i2)) {
++it_left;
} else {
++it_right;
}
}
AKANTU_DEBUG_INFO("found " << pbc_pair.size() << " pairs for direction " << dir);
}
__END_AKANTU__
diff --git a/src/model/boundary_condition.hh b/src/model/boundary_condition.hh
index 1e67df981..26543509c 100644
--- a/src/model/boundary_condition.hh
+++ b/src/model/boundary_condition.hh
@@ -1,105 +1,106 @@
/**
* @file boundary_condition.hh
*
* @author Dana Christen <dana.christen@gmail.com>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Dec 18 2015
*
* @brief XXX
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_BOUNDARY_CONDITION_HH__
#define __AKANTU_BOUNDARY_CONDITION_HH__
#include "aka_common.hh"
#include "boundary_condition_functor.hh"
#include "mesh.hh"
#include "fe_engine.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
template <class ModelType>
class BoundaryCondition {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
private:
/* ------------------------------------------------------------------------ */
/* Constructors / Destructors / Initializers */
/* ------------------------------------------------------------------------ */
public:
BoundaryCondition() : model(NULL), primal(NULL), dual(NULL), primal_increment(NULL) {}
///Initialize the boundary conditions
void initBC(ModelType & ptr, Array<Real> & primal, Array<Real> & dual);
void initBC(ModelType & ptr, Array<Real> & primal,
Array<Real> & primal_increment, Array<Real> & dual);
/* ------------------------------------------------------------------------ */
/* Methods and accessors */
/* ------------------------------------------------------------------------ */
public:
//inline void initBoundaryCondition();
template<typename FunctorType>
///Apply the boundary conditions
inline void applyBC(const FunctorType & func);
template<class FunctorType>
inline void applyBC(const FunctorType & func, const std::string & group_name);
template<class FunctorType>
inline void applyBC(const FunctorType & func, const ElementGroup & element_group);
AKANTU_GET_MACRO_NOT_CONST(Model, *model, ModelType &);
AKANTU_GET_MACRO_NOT_CONST(Primal,*primal, Array<Real> &);
AKANTU_GET_MACRO_NOT_CONST(Dual, *dual, Array<Real> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
template<class FunctorType, BC::Functor::Type type = FunctorType::type>
struct TemplateFunctionWrapper;
private:
ModelType * model;
Array<Real> * primal;
Array<Real> * dual;
Array<Real> * primal_increment;
};
__END_AKANTU__
#include "boundary_condition_tmpl.hh"
#endif /* __AKANTU_BOUNDARY_CONDITION_HH__ */
diff --git a/src/model/boundary_condition_functor.hh b/src/model/boundary_condition_functor.hh
index 2f75450c8..d3f1b9477 100644
--- a/src/model/boundary_condition_functor.hh
+++ b/src/model/boundary_condition_functor.hh
@@ -1,207 +1,206 @@
/**
* @file boundary_condition_functor.hh
*
-
* @author Dana Christen <dana.christen@gmail.com>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 03 2013
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Thu Oct 15 2015
*
- * @brief XXX
+ * @brief Definitions of the functors to apply boundary conditions
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_BOUNDARY_CONDITION_FUNCTOR_HH__
#define __AKANTU_BOUNDARY_CONDITION_FUNCTOR_HH__
#include "aka_common.hh"
#include "fe_engine.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
namespace BC {
typedef ::akantu::SpacialDirection Axis;
struct Functor {
enum Type {
_dirichlet,
_neumann
};
};
/* ------------------------------------------------------------------------ */
/* Dirichlet */
/* ------------------------------------------------------------------------ */
namespace Dirichlet {
/* ---------------------------------------------------------------------- */
class DirichletFunctor : public Functor {
protected:
DirichletFunctor() : axis(_x) {}
DirichletFunctor(Axis ax) : axis(ax) {}
public:
void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
public:
static const Type type = _dirichlet;
protected:
Axis axis;
};
/* ---------------------------------------------------------------------- */
class FlagOnly : public DirichletFunctor {
public:
FlagOnly(Axis ax = _x) : DirichletFunctor(ax) {}
public:
inline void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const;
};
/* ---------------------------------------------------------------------- */
class FreeBoundary : public DirichletFunctor {
public:
FreeBoundary(Axis ax = _x) : DirichletFunctor(ax) {}
public:
inline void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const;
};
/* ---------------------------------------------------------------------- */
class FixedValue : public DirichletFunctor {
public:
FixedValue(Real val, Axis ax = _x) : DirichletFunctor(ax), value(val) {}
public:
inline void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const;
protected:
Real value;
};
/* ---------------------------------------------------------------------- */
class IncrementValue : public DirichletFunctor {
public:
IncrementValue(Real val, Axis ax = _x) : DirichletFunctor(ax), value(val) {}
public:
inline void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const;
inline void setIncrement(Real val) { this->value = val; }
protected:
Real value;
};
} //end namespace Dirichlet
/* ------------------------------------------------------------------------ */
/* Neumann */
/* ------------------------------------------------------------------------ */
namespace Neumann {
/* ---------------------------------------------------------------------- */
class NeumannFunctor : public Functor {
protected:
NeumannFunctor() {}
public:
virtual void operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const = 0;
virtual ~NeumannFunctor(){}
public:
static const Type type = _neumann;
};
/* ---------------------------------------------------------------------- */
class FromHigherDim : public NeumannFunctor {
public:
FromHigherDim(const Matrix<Real> & mat) : bc_data(mat) {}
virtual ~FromHigherDim(){}
public:
inline void operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const;
protected:
Matrix<Real> bc_data;
};
/* ---------------------------------------------------------------------- */
class FromSameDim : public NeumannFunctor {
public:
FromSameDim(const Vector<Real> & vec) : bc_data(vec) {}
virtual ~FromSameDim(){}
public:
inline void operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const;
protected:
Vector<Real> bc_data;
};
/* ---------------------------------------------------------------------- */
class FreeBoundary : public NeumannFunctor {
public:
inline void operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const;
};
} //end namespace Neumann
} //end namespace BC
__END_AKANTU__
#include "boundary_condition_functor_inline_impl.cc"
#endif /* __AKANTU_BOUNDARY_CONDITION_FUNCTOR_HH__ */
diff --git a/src/model/boundary_condition_functor_inline_impl.cc b/src/model/boundary_condition_functor_inline_impl.cc
index 5b8c03422..074f86b95 100644
--- a/src/model/boundary_condition_functor_inline_impl.cc
+++ b/src/model/boundary_condition_functor_inline_impl.cc
@@ -1,130 +1,131 @@
/**
- * @file boundary_condition_functor.cc
+ * @file boundary_condition_functor_inline_impl.cc
*
* @author Dana Christen <dana.christen@gmail.com>
*
- * @date Wed Mar 18 11:30:00 2013
+ * @date creation: Fri May 03 2013
+ * @date last modification: Thu Oct 15 2015
*
- * @brief XXX
+ * @brief implementation of the BC::Functors
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#define DIRICHLET_SANITY_CHECK \
AKANTU_DEBUG_ASSERT(coord.size() <= flags.size(), \
"The coordinates and flags vectors given to the boundary" \
<< " condition functor have different sizes!"); \
AKANTU_DEBUG_ASSERT(primal.size() <= coord.size(), \
"The primal vector and coordinates vector given" \
<< " to the boundary condition functor have different sizes!");
#define NEUMANN_SANITY_CHECK \
AKANTU_DEBUG_ASSERT(coord.size() <= normals.size(), \
"The coordinates and normals vectors given to the" \
<< " boundary condition functor have different sizes!"); \
AKANTU_DEBUG_ASSERT(dual.size() <= coord.size(), \
"The dual vector and coordinates vector given to" \
<< " the boundary condition functor have different sizes!");
__BEGIN_AKANTU__
namespace BC {
namespace Dirichlet {
/* ---------------------------------------------------------------------- */
inline void FlagOnly::operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = true;
}
/* ---------------------------------------------------------------------- */
inline void FreeBoundary::operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = false;
}
/* ---------------------------------------------------------------------- */
inline void FixedValue::operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = true;
primal(axis) = value;
}
/* ---------------------------------------------------------------------- */
inline void IncrementValue::operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = true;
primal(axis) += value;
}
} // end namespace Dirichlet
/* ------------------------------------------------------------------------ */
/* Neumann */
/* ------------------------------------------------------------------------ */
namespace Neumann {
/* ---------------------------------------------------------------------- */
inline void FreeBoundary::operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const {
for(UInt i(0); i<dual.size(); ++i) {
dual(i) = 0.0;
}
}
/* -------------------------------------------------------------------------- */
inline void FromHigherDim::operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const {
dual.mul<false>(bc_data, normals);
}
/* -------------------------------------------------------------------------- */
inline void FromSameDim::operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const {
dual = bc_data;
}
} // end namespace Neumann
} // end namespace BC
__END_AKANTU__
diff --git a/src/model/boundary_condition_python_functor.cc b/src/model/boundary_condition_python_functor.cc
index 4ee348fbf..cae69819a 100644
--- a/src/model/boundary_condition_python_functor.cc
+++ b/src/model/boundary_condition_python_functor.cc
@@ -1,62 +1,66 @@
/**
* @file boundary_condition_python_functor.cc
*
-
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
+ * @date creation: Wed Aug 31 2011
+ * @date last modification: Fri Nov 13 2015
+ *
+ * @brief Interface for BC::Functor written in python
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "boundary_condition_python_functor.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
namespace BC {
void PythonFunctorDirichlet::operator ()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const{
this->callFunctor<void>("operator",node,flags,primal,coord);
}
void PythonFunctorNeumann::operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const{
this->callFunctor<void>("operator",quad_point,dual,coord,normals);
}
}//end namespace BC
__END_AKANTU__
diff --git a/src/model/boundary_condition_python_functor.hh b/src/model/boundary_condition_python_functor.hh
index e871574ac..ff93856d5 100644
--- a/src/model/boundary_condition_python_functor.hh
+++ b/src/model/boundary_condition_python_functor.hh
@@ -1,113 +1,116 @@
/**
* @file boundary_condition_python_functor.hh
*
-
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Fri Nov 13 2015
+ *
+ * @brief interface for BC::Functor writen in python
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "boundary_condition_functor.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_BOUNDARY_CONDITION_PYTHON_FUNCTOR_HH__
#define __AKANTU_BOUNDARY_CONDITION_PYTHON_FUNCTOR_HH__
/* -------------------------------------------------------------------------- */
#include "boundary_condition_functor.hh"
#include "python_functor.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
namespace BC {
class PythonFunctorDirichlet : public PythonFunctor, public Functor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PythonFunctorDirichlet(PyObject * obj) : PythonFunctor(obj) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
static const Type type = _dirichlet;
};
/* -------------------------------------------------------------------------- */
class PythonFunctorNeumann : public PythonFunctor, public Functor{
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PythonFunctorNeumann(PyObject * obj) : PythonFunctor(obj) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
static const Type type = _neumann;
};
}//end namespace BC
__END_AKANTU__
#endif /* __AKANTU_BOUNDARY_CONDITION_PYTHON_FUNCTOR_HH__ */
diff --git a/src/model/boundary_condition_tmpl.hh b/src/model/boundary_condition_tmpl.hh
index ab4e1bdce..af3cd9f3c 100644
--- a/src/model/boundary_condition_tmpl.hh
+++ b/src/model/boundary_condition_tmpl.hh
@@ -1,265 +1,265 @@
/**
* @file boundary_condition_tmpl.hh
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 03 2013
- * @date last modification: Mon Jun 23 2014
+ * @date last modification: Fri Oct 16 2015
*
- * @brief XXX
+ * @brief implementation of the applyBC
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<typename ModelType>
void BoundaryCondition<ModelType>::initBC(ModelType & model, Array<Real> & primal, Array<Real> & dual)
{
this->model = &model;
this->primal = &primal;
this->dual = &dual;
if(this->model->getSpatialDimension() > 1)
this->model->initFEEngineBoundary();
}
/* -------------------------------------------------------------------------- */
template<typename ModelType>
void BoundaryCondition<ModelType>::initBC(ModelType & model,
Array<Real> & primal,
Array<Real> & primal_increment,
Array<Real> & dual)
{
this->initBC(model, primal, dual);
this->primal_increment = &primal_increment;
}
/* -------------------------------------------------------------------------- */
/* Partial specialization for DIRICHLET functors */
template<typename ModelType>
template<typename FunctorType>
struct BoundaryCondition<ModelType>::TemplateFunctionWrapper<FunctorType, BC::Functor::_dirichlet> {
static inline void applyBC(const FunctorType & func,
const ElementGroup & group,
BoundaryCondition<ModelType> & bc_instance) {
ModelType & model = bc_instance.getModel();
Array<Real> & primal = bc_instance.getPrimal();
const Array<Real> & coords = model.getMesh().getNodes();
Array<bool> & boundary_flags = model.getBlockedDOFs();
UInt dim = model.getMesh().getSpatialDimension();
Array<Real>::vector_iterator primal_iter = primal.begin(primal.getNbComponent());
Array<Real>::const_vector_iterator coords_iter = coords.begin(dim);
Array<bool>::vector_iterator flags_iter = boundary_flags.begin(boundary_flags.getNbComponent());
for(ElementGroup::const_node_iterator nodes_it(group.node_begin());
nodes_it!= group.node_end();
++nodes_it) {
UInt n = *nodes_it;
Vector<bool> flag(flags_iter[n]);
Vector<Real> primal(primal_iter[n]);
Vector<Real> coords(coords_iter[n]);
func(n, flag, primal, coords);
}
}
};
/* -------------------------------------------------------------------------- */
/* Partial specialization for NEUMANN functors */
template<typename ModelType>
template<typename FunctorType>
struct BoundaryCondition<ModelType>::TemplateFunctionWrapper<FunctorType, BC::Functor::_neumann> {
static inline void applyBC(const FunctorType & func,
const ElementGroup & group,
BoundaryCondition<ModelType> & bc_instance) {
UInt dim = bc_instance.getModel().getSpatialDimension();
switch(dim) {
case 1: { AKANTU_DEBUG_TO_IMPLEMENT(); break; }
case 2:
case 3: {
applyBC(func, group, bc_instance, _not_ghost);
applyBC(func, group, bc_instance, _ghost);
break;
}
}
}
static inline void applyBC(const FunctorType & func,
const ElementGroup & group,
BoundaryCondition<ModelType> & bc_instance,
GhostType ghost_type) {
ModelType & model = bc_instance.getModel();
Array<Real> & dual = bc_instance.getDual();
const Mesh & mesh = model.getMesh();
const Array<Real> & nodes_coords = mesh.getNodes();
const FEEngine & fem_boundary = model.getFEEngineBoundary();
UInt dim = model.getSpatialDimension();
UInt nb_degree_of_freedom = dual.getNbComponent();
IntegrationPoint quad_point;
quad_point.ghost_type = ghost_type;
ElementGroup::type_iterator type_it = group.firstType(dim - 1, ghost_type);
ElementGroup::type_iterator type_end = group.lastType (dim - 1, ghost_type);
// Loop over the boundary element types
for(; type_it != type_end; ++type_it) {
const Array<UInt> & element_ids = group.getElements(*type_it, ghost_type);
Array<UInt>::const_scalar_iterator elem_iter = element_ids.begin();
Array<UInt>::const_scalar_iterator elem_iter_end = element_ids.end();
UInt nb_quad_points = fem_boundary.getNbIntegrationPoints(*type_it, ghost_type);
UInt nb_elements = element_ids.getSize();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*type_it);
Array<Real> * dual_before_integ = new Array<Real>(nb_elements * nb_quad_points,
nb_degree_of_freedom,
0.);
Array<Real> * quad_coords = new Array<Real>(nb_elements * nb_quad_points, dim);
const Array<Real> & normals_on_quad =
fem_boundary.getNormalsOnIntegrationPoints(*type_it, ghost_type);
fem_boundary.interpolateOnIntegrationPoints(nodes_coords, *quad_coords,
dim,
*type_it, ghost_type,
element_ids);
Array<Real>::const_vector_iterator normals_begin = normals_on_quad.begin(dim);
Array<Real>::const_vector_iterator normals_iter;
Array<Real>::const_vector_iterator quad_coords_iter = quad_coords->begin(dim);
Array<Real>::vector_iterator dual_iter = dual_before_integ->begin(nb_degree_of_freedom);
quad_point.type = *type_it;
for(; elem_iter != elem_iter_end; ++elem_iter) {
UInt el = *elem_iter;
quad_point.element = el;
normals_iter = normals_begin + el * nb_quad_points;
for(UInt q(0); q < nb_quad_points; ++q) {
quad_point.num_point = q;
func(quad_point,
*dual_iter,
*quad_coords_iter,
*normals_iter);
++dual_iter;
++quad_coords_iter;
++normals_iter;
}
}
delete quad_coords;
/* -------------------------------------------------------------------- */
// Initialization of iterators
Array<Real>::matrix_iterator dual_iter_mat =
dual_before_integ->begin(nb_degree_of_freedom,1);
elem_iter = element_ids.begin();
Array<Real>::const_matrix_iterator shapes_iter_begin =
fem_boundary.getShapes(*type_it, ghost_type).begin(1, nb_nodes_per_element);
Array<Real> * dual_by_shapes =
new Array<Real>(nb_elements*nb_quad_points, nb_degree_of_freedom*nb_nodes_per_element);
Array<Real>::matrix_iterator dual_by_shapes_iter =
dual_by_shapes->begin(nb_degree_of_freedom, nb_nodes_per_element);
Array<Real>::const_matrix_iterator shapes_iter;
/* -------------------------------------------------------------------- */
// Loop computing dual x shapes
for(; elem_iter != elem_iter_end; ++elem_iter) {
shapes_iter = shapes_iter_begin + *elem_iter*nb_quad_points;
for(UInt q(0); q < nb_quad_points; ++q,
++dual_iter_mat, ++dual_by_shapes_iter, ++shapes_iter) {
dual_by_shapes_iter->mul<false, false>(*dual_iter_mat, *shapes_iter);
}
}
delete dual_before_integ;
Array<Real> * dual_by_shapes_integ =
new Array<Real>(nb_elements, nb_degree_of_freedom*nb_nodes_per_element);
fem_boundary.integrate(*dual_by_shapes,
*dual_by_shapes_integ,
nb_degree_of_freedom*nb_nodes_per_element,
*type_it,
ghost_type,
element_ids);
delete dual_by_shapes;
// assemble the result into force vector
fem_boundary.assembleArray(*dual_by_shapes_integ,
dual,
model.getDOFSynchronizer().getLocalDOFEquationNumbers(),
nb_degree_of_freedom,
*type_it,
ghost_type,
element_ids);
delete dual_by_shapes_integ;
}
}
};
/* -------------------------------------------------------------------------- */
template<typename ModelType>
template<typename FunctorType>
inline void BoundaryCondition<ModelType>::applyBC(const FunctorType & func) {
GroupManager::const_element_group_iterator bit = model->getMesh().getGroupManager().element_group_begin();
GroupManager::const_element_group_iterator bend = model->getMesh().getGroupManager().element_group_end();
for(; bit != bend; ++bit) applyBC(func, *bit);
}
/* -------------------------------------------------------------------------- */
template<typename ModelType>
template<typename FunctorType>
inline void BoundaryCondition<ModelType>::applyBC(const FunctorType & func,
const std::string & group_name) {
try {
const ElementGroup & element_group = model->getMesh().getElementGroup(group_name);
applyBC(func, element_group);
} catch(akantu::debug::Exception e) {
AKANTU_EXCEPTION("Error applying a boundary condition onto \""
<< group_name << "\"! [" << e.what() <<"]");
}
}
/* -------------------------------------------------------------------------- */
template<typename ModelType>
template<typename FunctorType>
inline void BoundaryCondition<ModelType>::applyBC(const FunctorType & func,
const ElementGroup & element_group) {
#if !defined(AKANTU_NDEBUG)
if(element_group.getDimension() != model->getSpatialDimension() - 1)
AKANTU_DEBUG_WARNING("The group " << element_group.getName()
<< " does not contain only boundaries elements");
#endif
TemplateFunctionWrapper<FunctorType>::applyBC(func, element_group, *this);
}
__END_AKANTU__
diff --git a/src/model/common/neighborhood_base.cc b/src/model/common/neighborhood_base.cc
index 9b624f8b1..81f852d64 100644
--- a/src/model/common/neighborhood_base.cc
+++ b/src/model/common/neighborhood_base.cc
@@ -1,293 +1,296 @@
/**
* @file neighborhood_base.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Thu Oct 8 15:40:36 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
*
* @brief Implementation of generic neighborhood base
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "neighborhood_base.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
NeighborhoodBase::NeighborhoodBase(const SolidMechanicsModel & model,
const ElementTypeMapReal & quad_coordinates,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
model(model),
neighborhood_radius(0.),
spatial_grid(NULL),
is_creating_grid(false),
grid_synchronizer(NULL),
quad_coordinates(quad_coordinates),
spatial_dimension(this->model.getSpatialDimension()),
synch_registry(NULL) {
AKANTU_DEBUG_IN();
this->createSynchronizerRegistry(this);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
NeighborhoodBase::~NeighborhoodBase() {
AKANTU_DEBUG_IN();
delete spatial_grid;
delete grid_synchronizer;
delete synch_registry;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodBase::createSynchronizerRegistry(DataAccessor * data_accessor){
this->synch_registry = new SynchronizerRegistry(*data_accessor);
}
/* -------------------------------------------------------------------------- */
void NeighborhoodBase::initNeighborhood() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Creating the grid");
this->createGrid();
AKANTU_DEBUG_OUT();
}
/* ------------------------------------------------------------------------- */
void NeighborhoodBase::createGrid() {
AKANTU_DEBUG_IN();
const Real safety_factor = 1.2; // for the cell grid spacing
Mesh & mesh = this->model.getMesh();
mesh.computeBoundingBox();
const Vector<Real> & lower_bounds = mesh.getLocalLowerBounds();
const Vector<Real> & upper_bounds = mesh.getLocalUpperBounds();
Vector<Real> center = 0.5 * (upper_bounds + lower_bounds);
Vector<Real> spacing(spatial_dimension, this->neighborhood_radius * safety_factor);
spatial_grid = new SpatialGrid<IntegrationPoint>(spatial_dimension, spacing, center);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodBase::updatePairList() {
AKANTU_DEBUG_IN();
//// loop over all quads -> all cells
SpatialGrid<IntegrationPoint>::cells_iterator cell_it = spatial_grid->beginCells();
SpatialGrid<IntegrationPoint>::cells_iterator cell_end = spatial_grid->endCells();
Vector<Real> q1_coords(spatial_dimension);
Vector<Real> q2_coords(spatial_dimension);
IntegrationPoint q1;
IntegrationPoint q2;
UInt counter = 0;
for (; cell_it != cell_end; ++cell_it) {
AKANTU_DEBUG_INFO("Looping on next cell");
SpatialGrid<IntegrationPoint>::Cell::iterator first_quad =
spatial_grid->beginCell(*cell_it);
SpatialGrid<IntegrationPoint>::Cell::iterator last_quad =
spatial_grid->endCell(*cell_it);
for (;first_quad != last_quad; ++first_quad, ++counter){
q1 = *first_quad;
if (q1.ghost_type == _ghost) break;
Array<Real>::const_vector_iterator coords_type_1_it = this->quad_coordinates(q1.type, q1.ghost_type).begin(spatial_dimension);
q1_coords = coords_type_1_it[q1.global_num];
AKANTU_DEBUG_INFO("Current quadrature point in this cell: " << q1);
SpatialGrid<IntegrationPoint>::CellID cell_id = spatial_grid->getCellID(q1_coords);
/// loop over all the neighbouring cells of the current quad
SpatialGrid<IntegrationPoint>::neighbor_cells_iterator first_neigh_cell =
spatial_grid->beginNeighborCells(cell_id);
SpatialGrid<IntegrationPoint>::neighbor_cells_iterator last_neigh_cell =
spatial_grid->endNeighborCells(cell_id);
for (; first_neigh_cell != last_neigh_cell; ++first_neigh_cell) {
SpatialGrid<IntegrationPoint>::Cell::iterator first_neigh_quad =
spatial_grid->beginCell(*first_neigh_cell);
SpatialGrid<IntegrationPoint>::Cell::iterator last_neigh_quad =
spatial_grid->endCell(*first_neigh_cell);
// loop over the quadrature point in the current neighboring cell
for (;first_neigh_quad != last_neigh_quad; ++first_neigh_quad){
q2 = *first_neigh_quad;
Array<Real>::const_vector_iterator coords_type_2_it = this->quad_coordinates(q2.type, q2.ghost_type).begin(spatial_dimension);
q2_coords = coords_type_2_it[q2.global_num];
Real distance = q1_coords.distance(q2_coords);
if(distance <= this->neighborhood_radius + Math::getTolerance() &&
(q2.ghost_type == _ghost ||
(q2.ghost_type == _not_ghost && q1.global_num <= q2.global_num))) { // storing only half lists
pair_list[q2.ghost_type].push_back(std::make_pair(q1, q2));
}
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodBase::savePairs(const std::string & filename) const {
std::ofstream pout;
std::stringstream sstr;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int prank = comm.whoAmI();
sstr << filename << "." << prank;
pout.open(sstr.str().c_str());
for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type2 = (GhostType) gt;
PairList::const_iterator first_pair = pair_list[ghost_type2].begin();
PairList::const_iterator last_pair = pair_list[ghost_type2].end();
for(;first_pair != last_pair; ++first_pair) {
const IntegrationPoint & q1 = first_pair->first;
const IntegrationPoint & q2 = first_pair->second;
pout << q1 << " " << q2 << " " << std::endl;
}
}
}
/* -------------------------------------------------------------------------- */
void NeighborhoodBase::saveNeighborCoords(const std::string & filename) const {
/// this function is not optimazed and only used for tests on small meshes
/// @todo maybe optimize this function for better performance?
Vector<Real> q1_coords(spatial_dimension);
Vector<Real> q2_coords(spatial_dimension);
IntegrationPoint q1;
IntegrationPoint q2;
std::ofstream pout;
std::stringstream sstr;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int prank = comm.whoAmI();
sstr << filename << "." << prank;
pout.open(sstr.str().c_str());
/// loop over all the quads and write the position of their neighbors
SpatialGrid<IntegrationPoint>::cells_iterator cell_it = spatial_grid->beginCells();
SpatialGrid<IntegrationPoint>::cells_iterator cell_end = spatial_grid->endCells();
for (; cell_it != cell_end; ++cell_it) {
SpatialGrid<IntegrationPoint>::Cell::iterator first_quad =
spatial_grid->beginCell(*cell_it);
SpatialGrid<IntegrationPoint>::Cell::iterator last_quad =
spatial_grid->endCell(*cell_it);
for (;first_quad != last_quad; ++first_quad){
q1 = *first_quad;
Array<Real>::const_vector_iterator coords_type_1_it = this->quad_coordinates(q1.type, q1.ghost_type).begin(spatial_dimension);
q1_coords = coords_type_1_it[q1.global_num];
pout << "#neighbors for quad " << q1.global_num << std::endl;
pout << q1_coords << std::endl;
for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type2 = (GhostType) gt;
PairList::const_iterator first_pair = pair_list[ghost_type2].begin();
PairList::const_iterator last_pair = pair_list[ghost_type2].end();
for(;first_pair != last_pair; ++first_pair) {
if (q1 == first_pair->first && first_pair->second != q1) {
q2 = first_pair->second;
Array<Real>::const_vector_iterator coords_type_2_it =
this->quad_coordinates(q2.type, q2.ghost_type).begin(spatial_dimension);
q2_coords = coords_type_2_it[q2.global_num];
pout << q2_coords << std::endl;
}
if (q1 == first_pair->second && first_pair->first != q1) {
q2 = first_pair->first;
Array<Real>::const_vector_iterator coords_type_2_it =
this->quad_coordinates(q2.type, q2.ghost_type).begin(spatial_dimension);
q2_coords = coords_type_2_it[q2.global_num];
pout << q2_coords << std::endl;
}
}
}
}
}
}
/* -------------------------------------------------------------------------- */
void NeighborhoodBase::onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const RemovedElementsEvent & event) {
AKANTU_DEBUG_IN();
FEEngine & fem = this->model.getFEEngine();
UInt nb_quad = 0;
// Change the pairs in new global numbering
for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type2 = (GhostType) gt;
PairList::iterator first_pair = pair_list[ghost_type2].begin();
PairList::iterator last_pair = pair_list[ghost_type2].end();
for(;first_pair != last_pair; ++first_pair) {
IntegrationPoint & q1 = first_pair->first;
if(new_numbering.exists(q1.type, q1.ghost_type)) {
UInt q1_new_el = new_numbering(q1.type, q1.ghost_type)(q1.element);
AKANTU_DEBUG_ASSERT(q1_new_el != UInt(-1), "A local quadrature_point as been removed instead of just being renumbered");
q1.element = q1_new_el;
nb_quad = fem.getNbIntegrationPoints(q1.type, q1.ghost_type);
q1.global_num = nb_quad * q1.element + q1.num_point;
}
IntegrationPoint & q2 = first_pair->second;
if(new_numbering.exists(q2.type, q2.ghost_type)) {
UInt q2_new_el = new_numbering(q2.type, q2.ghost_type)(q2.element);
AKANTU_DEBUG_ASSERT(q2_new_el != UInt(-1), "A local quadrature_point as been removed instead of just being renumbered");
q2.element = q2_new_el;
nb_quad = fem.getNbIntegrationPoints(q2.type, q2.ghost_type);
q2.global_num = nb_quad * q2.element + q2.num_point;
}
}
}
this->grid_synchronizer->onElementsRemoved(element_list, new_numbering, event);
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/model/common/neighborhood_base.hh b/src/model/common/neighborhood_base.hh
index bacc6bf2f..91c308632 100644
--- a/src/model/common/neighborhood_base.hh
+++ b/src/model/common/neighborhood_base.hh
@@ -1,149 +1,152 @@
/**
* @file neighborhood_base.hh
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Thu Oct 8 15:27:33 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
*
* @brief Generic neighborhood of quadrature points
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NEIGHBORHOOD_BASE_HH__
#define __AKANTU_NEIGHBORHOOD_BASE_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "solid_mechanics_model.hh"
#include "aka_grid_dynamic.hh"
#include "grid_synchronizer.hh"
#include "aka_memory.hh"
#include "data_accessor.hh"
#include "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class NeighborhoodBase : public Memory,
public DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NeighborhoodBase(const SolidMechanicsModel & model,
const ElementTypeMapReal & quad_coordinates,
const ID & id = "neighborhood",
const MemoryID & memory_id = 0);
virtual ~NeighborhoodBase();
typedef std::vector< std::pair<IntegrationPoint, IntegrationPoint> > PairList;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// intialize the neighborhood
virtual void initNeighborhood();
/// create a synchronizer registry
void createSynchronizerRegistry(DataAccessor * data_accessor);
/// initialize the material computed parameter
inline void insertQuad(const IntegrationPoint & quad, const Vector<Real> & coords);
/// create the pairs of quadrature points
void updatePairList();
/// save the pairs of quadrature points in a file
void savePairs(const std::string & filename) const;
/// save the coordinates of all neighbors of a quad
void saveNeighborCoords(const std::string & filename) const;
/// create grid synchronizer and exchange ghost cells
virtual void createGridSynchronizer() = 0;
/// inherited function from MeshEventHandler
virtual void onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event);
protected:
/// create the grid
void createGrid();
/* -------------------------------------------------------------------------- */
/* Accessors */
/* -------------------------------------------------------------------------- */
public:
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
AKANTU_GET_MACRO(Model, model, const SolidMechanicsModel &);
/// return the object handling synchronizers
AKANTU_GET_MACRO(SynchronizerRegistry, *synch_registry, SynchronizerRegistry &);
AKANTU_GET_MACRO(PairLists, pair_list, const PairList *);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the model to which the neighborhood belongs
const SolidMechanicsModel & model;
/// Radius of impact: to determine if two quadrature points influence each other
Real neighborhood_radius;
/**
* the pairs of quadrature points
* 0: not ghost to not ghost
* 1: not ghost to ghost
*/
PairList pair_list[2];
/// the regular grid to construct/update the pair lists
SpatialGrid<IntegrationPoint> * spatial_grid;
bool is_creating_grid;
/// the grid synchronizer for parallel computations
GridSynchronizer * grid_synchronizer;
/// the quadrature point positions
const ElementTypeMapReal & quad_coordinates;
/// the spatial dimension of the problem
const UInt spatial_dimension;
/// synchronizer registry
SynchronizerRegistry * synch_registry;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "neighborhood_base_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_NEIGHBORHOOD_BASE_HH__ */
diff --git a/src/model/common/neighborhood_base_inline_impl.cc b/src/model/common/neighborhood_base_inline_impl.cc
index 8464f1a8e..5509f163e 100644
--- a/src/model/common/neighborhood_base_inline_impl.cc
+++ b/src/model/common/neighborhood_base_inline_impl.cc
@@ -1,45 +1,48 @@
/**
* @file neighborhood_base_inline_impl.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Mon Sep 21 18:25:31 2015
+ *
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Wed Nov 25 2015
*
* @brief Inline implementation of neighborhood base functions
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
__END_AKANTU__
//// includes
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline void NeighborhoodBase::insertQuad(const IntegrationPoint & quad, const Vector<Real> & coords) {
this->spatial_grid->insert(quad, coords);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
index d9c47abd4..55c7a296c 100644
--- a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
@@ -1,311 +1,314 @@
/**
* @file neighborhood_max_criterion.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Oct 14 21:31:07 2015
+ *
+ * @date creation: Thu Oct 15 2015
+ * @date last modification: Tue Nov 24 2015
*
* @brief Implementation of class NeighborhoodMaxCriterion
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "neighborhood_max_criterion.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
NeighborhoodMaxCriterion::NeighborhoodMaxCriterion(const SolidMechanicsModel & model,
const ElementTypeMapReal & quad_coordinates,
const ID & criterion_id,
const ID & id,
const MemoryID & memory_id) :
NeighborhoodBase(model, quad_coordinates, id, memory_id),
Parsable(_st_non_local, id),
is_highest("is_highest", id),
criterion(criterion_id, id)
{
AKANTU_DEBUG_IN();
this->registerParam("radius" , neighborhood_radius , 100.,
_pat_parsable | _pat_readable , "Non local radius");
Mesh & mesh = this->model.getMesh();
/// allocate the element type map arrays for _not_ghosts: One entry per quad
GhostType ghost_type = _not_ghost;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = mesh.lastType (spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
UInt new_size = this->quad_coordinates(*it, ghost_type).getSize();
this->is_highest.alloc(new_size, 1, *it, ghost_type, true);
this->criterion.alloc(new_size, 1, *it, ghost_type, true);
}
/// criterion needs allocation also for ghost
ghost_type = _ghost;
it = mesh.firstType(spatial_dimension, ghost_type);
last_type = mesh.lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
UInt new_size = this->quad_coordinates(*it, ghost_type).getSize();
this->criterion.alloc(new_size, 1, *it, ghost_type, true);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
NeighborhoodMaxCriterion::~NeighborhoodMaxCriterion() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::initNeighborhood() {
AKANTU_DEBUG_IN();
/// parse the input parameter
const Parser & parser = getStaticParser();
const ParserSection & section_neighborhood = *(parser.getSubSections(_st_neighborhood).first);
this->parseSection(section_neighborhood);
AKANTU_DEBUG_INFO("Creating the grid");
this->createGrid();
/// insert the non-ghost quads into the grid
this->insertAllQuads(_not_ghost);
/// store the number of current ghost elements for each type in the mesh
ElementTypeMap<UInt> nb_ghost_protected;
Mesh & mesh = this->model.getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
for(; it != last_type; ++it)
nb_ghost_protected(mesh.getNbElement(*it, _ghost), *it, _ghost);
/// create the grid synchronizer
this->createGridSynchronizer();
/// insert the ghost quads into the grid
this->insertAllQuads(_ghost);
/// create the pair lists
this->updatePairList();
/// remove the unneccessary ghosts
this->cleanupExtraGhostElements(nb_ghost_protected);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::createGridSynchronizer() {
this->is_creating_grid = true;
std::set<SynchronizationTag> tags;
tags.insert(_gst_nh_criterion);
std::stringstream sstr; sstr << getID() << ":grid_synchronizer";
this->grid_synchronizer = GridSynchronizer::createGridSynchronizer(this->model.getMesh(),
*spatial_grid,
sstr.str(),
synch_registry,
tags, 0, false);
this->is_creating_grid = false;
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::insertAllQuads(const GhostType & ghost_type) {
IntegrationPoint q;
q.ghost_type = ghost_type;
Mesh & mesh = this->model.getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = mesh.lastType (spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
UInt nb_quad = this->model.getFEEngine().getNbIntegrationPoints(*it, ghost_type);
const Array<Real> & quads = this->quad_coordinates(*it, ghost_type);
q.type = *it;
Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
for (UInt e = 0; e < nb_element; ++e) {
q.element = e;
for (UInt nq = 0; nq < nb_quad; ++nq) {
q.num_point = nq;
q.global_num = q.element * nb_quad + nq;
spatial_grid->insert(q, *quad);
++quad;
}
}
}
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::findMaxQuads(std::vector<IntegrationPoint> & max_quads) {
AKANTU_DEBUG_IN();
/// clear the element type maps
this->is_highest.clear();
this->criterion.clear();
/// update the values of the criterion
const ID field_name = criterion.getName();
for (UInt m = 0; m < this->model.getNbMaterials(); ++m) {
const Material & material = this->model.getMaterial(m);
if (material.isInternal<Real>(field_name, _ek_regular))
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType ghost_type = (GhostType) g;
material.flattenInternal(field_name, criterion, ghost_type, _ek_regular);
}
}
/// start the exchange the value of the criterion on the ghost elements
SynchronizerRegistry & synch_registry = this->model.getSynchronizerRegistry();
synch_registry.asynchronousSynchronize(_gst_nh_criterion);
/// compare to not-ghost neighbors
checkNeighbors(_not_ghost);
/// finish the exchange
synch_registry.waitEndSynchronize(_gst_nh_criterion);
/// compare to ghost neighbors
checkNeighbors(_ghost);
/// extract the quads with highest criterion in their neighborhood
IntegrationPoint quad;
quad.ghost_type = _not_ghost;
Mesh & mesh = this->model.getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost);
for(; it != last_type; ++it) {
quad.type = *it;
Array<bool>::const_scalar_iterator is_highest_it = is_highest(*it, _not_ghost).begin();
Array<bool>::const_scalar_iterator is_highest_end = is_highest(*it, _not_ghost).end();
UInt nb_quadrature_points = this->model.getFEEngine().getNbIntegrationPoints(*it, _not_ghost);
UInt q = 0;
/// loop over is_highest for the current element type
for (;is_highest_it != is_highest_end; ++is_highest_it, ++q) {
if (*is_highest_it) {
/// gauss point has the highest stress in his neighbourhood
quad.element = q / nb_quadrature_points;
quad.global_num = q;
quad.num_point = q % nb_quadrature_points;
max_quads.push_back(quad);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::checkNeighbors(const GhostType & ghost_type2) {
AKANTU_DEBUG_IN();
PairList::const_iterator first_pair = pair_list[ghost_type2].begin();
PairList::const_iterator last_pair = pair_list[ghost_type2].end();
// Compute the weights
for(;first_pair != last_pair; ++first_pair) {
const IntegrationPoint & lq1 = first_pair->first;
const IntegrationPoint & lq2 = first_pair->second;
Array<bool> & has_highest_eq_stress_1 = is_highest(lq1.type, lq1.ghost_type);
const Array<Real> & criterion_1 = this->criterion(lq1.type, lq1.ghost_type);
const Array<Real> & criterion_2 = this->criterion(lq2.type, lq2.ghost_type);
if(criterion_1(lq1.global_num) < criterion_2(lq2.global_num))
has_highest_eq_stress_1(lq1.global_num) = false;
else if (ghost_type2 != _ghost) {
Array<bool> & has_highest_eq_stress_2 = is_highest(lq2.type, lq2.ghost_type);
has_highest_eq_stress_2(lq2.global_num) = false;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::cleanupExtraGhostElements(const ElementTypeMap<UInt> & nb_ghost_protected) {
Mesh & mesh = this->model.getMesh();
/// create remove elements event
RemovedElementsEvent remove_elem(mesh);
/// create set of ghosts to keep
std::set<Element> relevant_ghost_elements;
PairList::const_iterator first_pair = pair_list[_ghost].begin();
PairList::const_iterator last_pair = pair_list[_ghost].end();
for(;first_pair != last_pair; ++first_pair) {
const IntegrationPoint & q2 = first_pair->second;
relevant_ghost_elements.insert(q2);
}
Array<Element> ghosts_to_erase(0);
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
Element element;
element.ghost_type = _ghost;
std::set<Element>::const_iterator end = relevant_ghost_elements.end();
for(; it != last_type; ++it) {
element.type = *it;
UInt nb_ghost_elem = mesh.getNbElement(*it, _ghost);
UInt nb_ghost_elem_protected = 0;
try {
nb_ghost_elem_protected = nb_ghost_protected(*it, _ghost);
} catch (...) {}
if(!remove_elem.getNewNumbering().exists(*it, _ghost))
remove_elem.getNewNumbering().alloc(nb_ghost_elem, 1, *it, _ghost);
else remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem);
Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
for (UInt g = 0; g < nb_ghost_elem; ++g) {
element.element = g;
if (element.element >= nb_ghost_elem_protected && relevant_ghost_elements.find(element) == end) {
ghosts_to_erase.push_back(element);
new_numbering(element.element) = UInt(-1);
}
}
/// renumber remaining ghosts
UInt ng = 0;
for (UInt g = 0; g < nb_ghost_elem; ++g) {
if (new_numbering(g) != UInt(-1)) {
new_numbering(g) = ng;
++ng;
}
}
}
mesh.sendEvent(remove_elem);
this->onElementsRemoved(ghosts_to_erase, remove_elem.getNewNumbering(), remove_elem);
}
__END_AKANTU__
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
index e2e4261c7..a3fabc793 100644
--- a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
@@ -1,121 +1,124 @@
/**
* @file neighborhood_max_criterion.hh
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Oct 14 20:59:00 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Thu Oct 15 2015
*
* @brief Neighborhood to find a maximum value in a neighborhood
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NEIGHBORHOOD_MAX_CRITERION_BASE_HH__
#define __AKANTU_NEIGHBORHOOD_MAX_CRITERION_BASE_HH__
/* -------------------------------------------------------------------------- */
#include "neighborhood_base.hh"
#include "parsable.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class NeighborhoodMaxCriterion : public NeighborhoodBase,
public Parsable{
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NeighborhoodMaxCriterion(const SolidMechanicsModel & model,
const ElementTypeMapReal & quad_coordinates,
const ID & criterion_id,
const ID & id = "neighborhood_max_criterion",
const MemoryID & memory_id = 0);
virtual ~NeighborhoodMaxCriterion();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the neighborhood
virtual void initNeighborhood();
/// create grid synchronizer and exchange ghost cells
virtual void createGridSynchronizer();
/// find the quads which have the maximum criterion in their neighborhood
void findMaxQuads(std::vector<IntegrationPoint> & max_quads);
protected:
/// remove unneccessary ghost elements
void cleanupExtraGhostElements(const ElementTypeMap<UInt> & nb_ghost_protected);
/// insert the quadrature points in the grid
void insertAllQuads(const GhostType & ghost_type);
/// compare criterion with neighbors
void checkNeighbors(const GhostType & ghost_type);
/* -------------------------------------------------------------------------- */
/* DataAccessor inherited members */
/* -------------------------------------------------------------------------- */
public:
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
/* -------------------------------------------------------------------------- */
/* Accessors */
/* -------------------------------------------------------------------------- */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// a boolean to store the information if a quad has the max
/// criterion in the neighborhood
ElementTypeMapArray<bool> is_highest;
/// an element type map to store the flattened internal of the criterion
ElementTypeMapReal criterion;
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "neighborhood_max_criterion_inline_impl.cc"
#endif /* __AKANTU_NEIGHBORHOOD_MAX_CRITERION_BASE_HH__ */
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
index 2eb6a3753..9b039428c 100644
--- a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
@@ -1,77 +1,80 @@
/**
- * @file neighborhood_max_criterion_inline_implementation.cc
+ * @file neighborhood_max_criterion_inline_impl.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Oct 14 21:31:07 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Thu Oct 15 2015
*
* @brief Implementation of inline functions for class NeighborhoodMaxCriterion
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NEIGHBORHOOD_MAX_CRITERION_INLINE_IMPL_CC__
#define __AKANTU_NEIGHBORHOOD_MAX_CRITERION_INLINE_IMPL_CC__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline UInt NeighborhoodMaxCriterion::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
UInt nb_quadrature_points = this->model.getNbIntegrationPoints(elements);
UInt size = 0;
if(tag == _gst_nh_criterion) {
size += sizeof(Real) * nb_quadrature_points;
}
return size;
}
/* -------------------------------------------------------------------------- */
inline void NeighborhoodMaxCriterion::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
if(tag == _gst_nh_criterion) {
this->packElementalDataHelper(criterion,
buffer, elements,true, this->model.getFEEngine());
}
}
/* -------------------------------------------------------------------------- */
inline void NeighborhoodMaxCriterion::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
if(tag == _gst_nh_criterion) {
this->unpackElementalDataHelper(criterion,
buffer, elements, true, this->model.getFEEngine());
}
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_NEIGHBORHOOD_MAX_CRITERION_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/non_local_manager.cc b/src/model/common/non_local_toolbox/non_local_manager.cc
index 2cb119858..8690b24a8 100644
--- a/src/model/common/non_local_toolbox/non_local_manager.cc
+++ b/src/model/common/non_local_toolbox/non_local_manager.cc
@@ -1,619 +1,623 @@
/**
* @file non_local_manager.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Mon Sep 21 15:32:10 2015
+ *
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Wed Dec 16 2015
*
* @brief Implementation of non-local manager
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "non_local_manager.hh"
#include "non_local_neighborhood.hh"
#include "material_non_local.hh"
#include "base_weight_function.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
NonLocalManager::NonLocalManager(SolidMechanicsModel & model,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
Parsable(_st_neighborhoods, id),
model(model),
quad_positions("quad_positions", id),
volumes("volumes", id),
spatial_dimension(this->model.getSpatialDimension()),
compute_stress_calls(0),
dummy_registry(NULL),
dummy_grid(NULL) {
Mesh & mesh = this->model.getMesh();
mesh.registerEventHandler(*this);
/// initialize the element type map array
/// it will be resized to nb_quad * nb_element during the computation of coords
mesh.initElementTypeMapArray(quad_positions, spatial_dimension, spatial_dimension, false, _ek_regular, true);
this->initElementTypeMap(1, volumes, this->model.getFEEngine());
/// parse the neighborhood information from the input file
const Parser & parser = getStaticParser();
/// iterate over all the non-local sections and store them in a map
std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
weight_sect = parser.getSubSections(_st_non_local);
Parser::const_section_iterator it = weight_sect.first;
for (; it != weight_sect.second; ++it) {
const ParserSection & section = *it;
ID name = section.getName();
this->weight_function_types[name] = section;
}
this->dummy_registry = new SynchronizerRegistry(this->dummy_accessor);
}
/* -------------------------------------------------------------------------- */
NonLocalManager::~NonLocalManager() {
/// delete neighborhoods
NeighborhoodMap::iterator it;
for (it = neighborhoods.begin(); it != neighborhoods.end(); ++it) {
if(it->second) delete it->second;
}
/// delete non-local variables
std::map<ID, NonLocalVariable *>::iterator it_variables;
for (it_variables = non_local_variables.begin(); it_variables != non_local_variables.end(); ++it_variables) {
if(it_variables->second) delete it_variables->second;
}
std::map<ID, ElementTypeMapReal *>::iterator it_internals;
for (it_internals = weight_function_internals.begin(); it_internals != weight_function_internals.end(); ++it_internals) {
if(it_internals->second) delete it_internals->second;
}
std::map<ID, GridSynchronizer * >::iterator grid_synch_it;
for (grid_synch_it = dummy_synchronizers.begin(); grid_synch_it != dummy_synchronizers.end(); ++grid_synch_it) {
if(grid_synch_it->second) delete grid_synch_it->second;
}
/// delete all objects related to the dummy synchronizers
delete dummy_registry;
delete dummy_grid;
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::setJacobians(const FEEngine & fe_engine, const ElementKind & kind) {
Mesh & mesh = this->model.getMesh();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, kind);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt, kind);
for(; it != last_type; ++it) {
jacobians(*it, gt) = &fe_engine.getIntegratorInterface().getJacobians(*it, gt);
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::createNeighborhood(const ID & weight_func, const ID & neighborhood_id) {
AKANTU_DEBUG_IN();
const ParserSection & section = this->weight_function_types[weight_func];
const ID weight_func_type = section.getOption();
/// create new neighborhood for given ID
std::stringstream sstr; sstr << id << ":neighborhood:" << neighborhood_id;
if (weight_func_type == "base_wf")
neighborhoods[neighborhood_id] = new NonLocalNeighborhood<BaseWeightFunction>(*this, this->quad_positions, sstr.str());
else if (weight_func_type == "remove_wf")
neighborhoods[neighborhood_id] = new NonLocalNeighborhood<RemoveDamagedWeightFunction>(*this, this->quad_positions, sstr.str());
else if (weight_func_type == "stress_wf")
neighborhoods[neighborhood_id] = new NonLocalNeighborhood<StressBasedWeightFunction>(*this, this->quad_positions, sstr.str());
else if (weight_func_type == "damage_wf")
neighborhoods[neighborhood_id] = new NonLocalNeighborhood<DamagedWeightFunction>(*this, this->quad_positions, sstr.str());
else
AKANTU_EXCEPTION("error in weight function type provided in material file");
neighborhoods[neighborhood_id]->parseSection(section);
neighborhoods[neighborhood_id]->initNeighborhood();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::createNeighborhoodSynchronizers() {
/// exchange all the neighborhood IDs, so that every proc knows how many neighborhoods exist globally
/// First: Compute locally the maximum ID size
UInt max_id_size = 0;
UInt current_size = 0;
NeighborhoodMap::const_iterator it;
for (it = neighborhoods.begin(); it != neighborhoods.end(); ++it) {
current_size = it->first.size();
if (current_size > max_id_size)
max_id_size = current_size;
}
/// get the global maximum ID size on each proc
StaticCommunicator & static_communicator = akantu::StaticCommunicator::getStaticCommunicator();
static_communicator.allReduce(&max_id_size, 1, _so_max);
/// get the rank for this proc and the total nb proc
UInt prank = static_communicator.whoAmI();
UInt psize = static_communicator.getNbProc();
/// exchange the number of neighborhoods on each proc
Array<Int> nb_neighborhoods_per_proc(psize);
nb_neighborhoods_per_proc(prank) = neighborhoods.size();
static_communicator.allGather(nb_neighborhoods_per_proc.storage(), 1);
/// compute the total number of neighborhoods
UInt nb_neighborhoods_global = std::accumulate(nb_neighborhoods_per_proc.begin(),
nb_neighborhoods_per_proc.end(), 0);
/// allocate an array of chars to store the names of all neighborhoods
Array<char> buffer(nb_neighborhoods_global, max_id_size);
/// starting index on this proc
UInt starting_index = std::accumulate(nb_neighborhoods_per_proc.begin(),
nb_neighborhoods_per_proc.begin() + prank, 0);
it = neighborhoods.begin();
/// store the names of local neighborhoods in the buffer
for (UInt i = 0; i < neighborhoods.size(); ++i, ++it) {
UInt c = 0;
for (; c < it->first.size(); ++c)
buffer(i + starting_index, c) = it->first[c];
for (; c < max_id_size; ++c)
buffer(i + starting_index, c) = char( 0 );
}
/// store the nb of data to send in the all gather
Array<Int> buffer_size(nb_neighborhoods_per_proc);
buffer_size *= max_id_size;
/// exchange the names of all the neighborhoods with all procs
static_communicator.allGatherV(buffer.storage(), buffer_size.storage());
for (UInt i = 0; i < nb_neighborhoods_global; ++i) {
std::stringstream neighborhood_id;
for(UInt c = 0; c < max_id_size; ++c) {
if (buffer(i,c) == char( 0 )) break;
neighborhood_id << buffer(i,c);
}
global_neighborhoods.insert(neighborhood_id.str());
}
/// this proc does not know all the neighborhoods -> create dummy
/// grid so that this proc can participate in the all gather for
/// detecting the overlap of neighborhoods this proc doesn't know
Vector<Real> grid_center(this->spatial_dimension);
for(UInt s = 0; s < this->spatial_dimension; ++s)
grid_center(s) = std::numeric_limits<Real>::max();
dummy_grid = new SpatialGrid<IntegrationPoint>(spatial_dimension, 0., grid_center);
std::set<SynchronizationTag> tags;
tags.insert(_gst_mnl_for_average);
tags.insert(_gst_mnl_weight);
std::set<ID>::const_iterator global_neighborhoods_it = global_neighborhoods.begin();
for (; global_neighborhoods_it != global_neighborhoods.end(); ++global_neighborhoods_it) {
it = neighborhoods.find(*global_neighborhoods_it);
if (it != neighborhoods.end()) {
it->second->createGridSynchronizer();
}
else {
ID neighborhood_name = *global_neighborhoods_it;
std::stringstream sstr; sstr << getID() << ":" << neighborhood_name << ":grid_synchronizer";
dummy_synchronizers[neighborhood_name] = GridSynchronizer::createGridSynchronizer(this->model.getMesh(),
*dummy_grid,
sstr.str(),
dummy_registry,
tags, 0, false);
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::flattenInternal(ElementTypeMapReal & internal_flat,
const GhostType & ghost_type,
const ElementKind & kind) {
const ID field_name = internal_flat.getName();
for (UInt m = 0; m < this->non_local_materials.size(); ++m) {
Material & material = *(this->non_local_materials[m]);
if (material.isInternal<Real>(field_name, kind))
material.flattenInternal(field_name, internal_flat, ghost_type, kind);
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::averageInternals(const GhostType & ghost_type) {
/// update the weights of the weight function
if (ghost_type == _not_ghost)
this->computeWeights();
/// loop over all neighborhoods and compute the non-local variables
NeighborhoodMap::iterator neighborhood_it = neighborhoods.begin();
NeighborhoodMap::iterator neighborhood_end = neighborhoods.end();
for (; neighborhood_it != neighborhood_end; ++neighborhood_it) {
/// loop over all the non-local variables of the given neighborhood
std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.begin();
std::map<ID, NonLocalVariable *>::iterator non_local_variable_end = non_local_variables.end();
for(; non_local_variable_it != non_local_variable_end; ++non_local_variable_it) {
NonLocalVariable * non_local_var = non_local_variable_it->second;
neighborhood_it->second->weightedAverageOnNeighbours(non_local_var->local, non_local_var->non_local, non_local_var->nb_component, ghost_type);
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::init(){
/// store the number of current ghost elements for each type in the mesh
ElementTypeMap<UInt> nb_ghost_protected;
Mesh & mesh = this->model.getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
for(; it != last_type; ++it)
nb_ghost_protected(mesh.getNbElement(*it, _ghost), *it, _ghost);
/// exchange the missing ghosts for the non-local neighborhoods
this->createNeighborhoodSynchronizers();
/// insert the ghost quadrature points of the non-local materials into the non-local neighborhoods
for(UInt m = 0; m < this->non_local_materials.size(); ++m) {
switch (spatial_dimension) {
case 1:
dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m])).insertQuadsInNeighborhoods(_ghost);
break;
case 2:
dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m])).insertQuadsInNeighborhoods(_ghost);
break;
case 3:
dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m])).insertQuadsInNeighborhoods(_ghost);
break;
}
}
FEEngine & fee = this->model.getFEEngine();
this->updatePairLists();
/// cleanup the unneccessary ghost elements
this->cleanupExtraGhostElements(nb_ghost_protected);
this->setJacobians(fee, _ek_regular);
this->initNonLocalVariables();
this->computeWeights();
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::initNonLocalVariables(){
/// loop over all the non-local variables
std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.begin();
std::map<ID, NonLocalVariable *>::iterator non_local_variable_end = non_local_variables.end();
for(; non_local_variable_it != non_local_variable_end; ++non_local_variable_it) {
NonLocalVariable & variable = *(non_local_variable_it->second);
this->initElementTypeMap(variable.nb_component, variable.non_local, this->model.getFEEngine());
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::initElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
const FEEngine & fee, const ElementKind el_kind) {
Mesh & mesh = this->model.getMesh();
/// need to resize the arrays
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, el_kind);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt, el_kind);
for(; it != end; ++it) {
ElementType el_type = *it;
UInt nb_element = mesh.getNbElement(*it, gt);
UInt nb_quads = fee.getNbIntegrationPoints(*it, gt);
if (!element_map.exists(el_type, gt)) {
element_map.alloc(nb_element * nb_quads,
nb_component,
el_type,
gt);
}
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::distributeInternals(ElementKind kind) {
/// loop over all the non-local variables and copy back their values into the materials
std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.begin();
std::map<ID, NonLocalVariable *>::iterator non_local_variable_end = non_local_variables.end();
for(; non_local_variable_it != non_local_variable_end; ++non_local_variable_it) {
NonLocalVariable * non_local_var = non_local_variable_it->second;
const ID field_name = non_local_var->non_local.getName();
/// loop over all the materials
for (UInt m = 0; m < this->non_local_materials.size(); ++m) {
if (this->non_local_materials[m]->isInternal<Real>(field_name, kind))
switch (spatial_dimension) {
case 1:
dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m])).updateNonLocalInternals(non_local_var->non_local, field_name, non_local_var->nb_component);
break;
case 2:
dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m])).updateNonLocalInternals(non_local_var->non_local, field_name, non_local_var->nb_component);
break;
case 3:
dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m])).updateNonLocalInternals(non_local_var->non_local, field_name, non_local_var->nb_component);
break;
}
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::computeAllNonLocalStresses() {
/// update the flattened version of the internals
std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.begin();
std::map<ID, NonLocalVariable *>::iterator non_local_variable_end = non_local_variables.end();
for(; non_local_variable_it != non_local_variable_end; ++non_local_variable_it) {
non_local_variable_it->second->local.clear();
non_local_variable_it->second->non_local.clear();
for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type = (GhostType) gt;
this->flattenInternal(non_local_variable_it->second->local, ghost_type, _ek_regular);
}
}
this->volumes.clear();
///loop over all the neighborhoods and compute intiate the
/// exchange of the non-local_variables
// std::set<ID>::const_iterator global_neighborhood_it = global_neighborhoods.begin();
// NeighborhoodMap::iterator it;
// for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
// it = neighborhoods.find(*global_neighborhood_it);
// if (it != neighborhoods.end())
// it->second->getSynchronizerRegistry().asynchronousSynchronize(_gst_mnl_for_average);
// else
// dummy_synchronizers[*global_neighborhood_it]->asynchronousSynchronize(dummy_accessor, _gst_mnl_for_average);
// }
NeighborhoodMap::iterator neighborhood_it = neighborhoods.begin();
//NeighborhoodMap::iterator neighborhood_end = neighborhoods.end();
for(; neighborhood_it != neighborhoods.end(); ++neighborhood_it) {
neighborhood_it->second->getSynchronizerRegistry().asynchronousSynchronize(_gst_mnl_for_average);
}
this->averageInternals(_not_ghost);
AKANTU_DEBUG_INFO("Wait distant non local stresses");
/// loop over all the neighborhoods and block until all non-local
/// variables have been exchanged
// global_neighborhood_it = global_neighborhoods.begin();
// for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
// it = neighborhoods.find(*global_neighborhood_it);
// if (it != neighborhoods.end())
// it->second->getSynchronizerRegistry().waitEndSynchronize(_gst_mnl_for_average);
// else
// dummy_synchronizers[*global_neighborhood_it]->waitEndSynchronize(dummy_accessor, _gst_mnl_for_average);
// }
neighborhood_it = neighborhoods.begin();
for(; neighborhood_it != neighborhoods.end(); ++neighborhood_it) {
neighborhood_it->second->getSynchronizerRegistry().waitEndSynchronize(_gst_mnl_for_average);
}
this->averageInternals(_ghost);
/// copy the results in the materials
this->distributeInternals(_ek_regular);
/// loop over all the materials and update the weights
for (UInt m = 0; m < this->non_local_materials.size(); ++m) {
switch (spatial_dimension) {
case 1:
dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m])).computeNonLocalStresses(_not_ghost); break;
case 2:
dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m])).computeNonLocalStresses(_not_ghost); break;
case 3:
dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m])).computeNonLocalStresses(_not_ghost); break;
}
}
++this->compute_stress_calls;
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::cleanupExtraGhostElements(ElementTypeMap<UInt> & nb_ghost_protected) {
typedef std::set<Element> ElementSet;
ElementSet relevant_ghost_elements;
ElementSet to_keep_per_neighborhood;
/// loop over all the neighborhoods and get their protected ghosts
NeighborhoodMap::iterator neighborhood_it = neighborhoods.begin();
NeighborhoodMap::iterator neighborhood_end = neighborhoods.end();
for (; neighborhood_it != neighborhood_end; ++neighborhood_it) {
neighborhood_it->second->cleanupExtraGhostElements(to_keep_per_neighborhood);
ElementSet::const_iterator it = to_keep_per_neighborhood.begin();
for(; it != to_keep_per_neighborhood.end(); ++it)
relevant_ghost_elements.insert(*it);
to_keep_per_neighborhood.clear();
}
/// remove all unneccessary ghosts from the mesh
/// Create list of element to remove and new numbering for element to keep
Mesh & mesh = this->model.getMesh();
ElementSet ghost_to_erase;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
RemovedElementsEvent remove_elem(mesh);
Element element;
element.ghost_type = _ghost;
for(; it != last_type; ++it) {
element.type = *it;
UInt nb_ghost_elem = mesh.getNbElement(*it, _ghost);
UInt nb_ghost_elem_protected = 0;
try {
nb_ghost_elem_protected = nb_ghost_protected(*it, _ghost);
} catch (...) {}
if(!remove_elem.getNewNumbering().exists(*it, _ghost))
remove_elem.getNewNumbering().alloc(nb_ghost_elem, 1, *it, _ghost);
else remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem);
Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
for (UInt g = 0; g < nb_ghost_elem; ++g) {
element.element = g;
if (element.element >= nb_ghost_elem_protected &&
relevant_ghost_elements.find(element) == relevant_ghost_elements.end()) {
remove_elem.getList().push_back(element);
new_numbering(element.element) = UInt(-1);
}
}
/// renumber remaining ghosts
UInt ng = 0;
for (UInt g = 0; g < nb_ghost_elem; ++g) {
if (new_numbering(g) != UInt(-1)) {
new_numbering(g) = ng;
++ng;
}
}
}
it = mesh.firstType(spatial_dimension, _not_ghost);
last_type = mesh.lastType(spatial_dimension, _not_ghost);
for(; it != last_type; ++it) {
UInt nb_elem = mesh.getNbElement(*it, _not_ghost);
if(!remove_elem.getNewNumbering().exists(*it, _not_ghost))
remove_elem.getNewNumbering().alloc(nb_elem, 1, *it, _not_ghost);
Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _not_ghost);
for (UInt e = 0; e < nb_elem; ++e) {
new_numbering(e) = e;
}
}
mesh.sendEvent(remove_elem);
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const RemovedElementsEvent & event) {
FEEngine & fee = this->model.getFEEngine();
this->removeIntegrationPointsFromMap(event.getNewNumbering(), spatial_dimension, quad_positions, fee, _ek_regular);
this->removeIntegrationPointsFromMap(event.getNewNumbering(), 1, volumes, fee, _ek_regular);
/// loop over all the neighborhoods and call onElementsRemoved
std::set<ID>::const_iterator global_neighborhood_it = global_neighborhoods.begin();
NeighborhoodMap::iterator it;
for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
it = neighborhoods.find(*global_neighborhood_it);
if (it != neighborhoods.end())
it->second->onElementsRemoved(element_list, new_numbering, event);
else
dummy_synchronizers[*global_neighborhood_it]->onElementsRemoved(element_list, new_numbering, event);
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::onElementsAdded(__attribute__((unused)) const Array<Element> & element_list,
__attribute__((unused)) const NewElementsEvent & event) {
this->resizeElementTypeMap(1, volumes, model.getFEEngine());
this->resizeElementTypeMap(spatial_dimension, quad_positions, model.getFEEngine());
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::resizeElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
const FEEngine & fee, const ElementKind el_kind) {
Mesh & mesh = this->model.getMesh();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, el_kind);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt, el_kind);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it, gt);
UInt nb_quads = fee.getNbIntegrationPoints(*it, gt);
if(!element_map.exists(*it, gt))
element_map.alloc(nb_element * nb_quads, nb_component, *it, gt);
else
element_map(*it, gt).resize(nb_element * nb_quads);
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::removeIntegrationPointsFromMap(const ElementTypeMapArray<UInt> & new_numbering,
UInt nb_component, ElementTypeMapReal & element_map,
const FEEngine & fee, const ElementKind el_kind) {
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
ElementTypeMapArray<UInt>::type_iterator it = new_numbering.firstType(_all_dimensions, gt, el_kind);
ElementTypeMapArray<UInt>::type_iterator end = new_numbering.lastType(_all_dimensions, gt, el_kind);
for (; it != end; ++it) {
ElementType type = *it;
if(element_map.exists(type, gt)){
const Array<UInt> & renumbering = new_numbering(type, gt);
Array<Real> & vect = element_map(type, gt);
UInt nb_quad_per_elem = fee.getNbIntegrationPoints(type, gt);
Array<Real> tmp(renumbering.getSize()*nb_quad_per_elem, nb_component);
AKANTU_DEBUG_ASSERT(tmp.getSize() == vect.getSize(), "Something strange append some mater was created from nowhere!!");
AKANTU_DEBUG_ASSERT(tmp.getSize() == vect.getSize(), "Something strange append some mater was created or disappeared in "<< vect.getID() << "("<< vect.getSize() <<"!=" << tmp.getSize() <<") ""!!");
UInt new_size = 0;
for (UInt i = 0; i < renumbering.getSize(); ++i) {
UInt new_i = renumbering(i);
if(new_i != UInt(-1)) {
memcpy(tmp.storage() + new_i * nb_component * nb_quad_per_elem,
vect.storage() + i * nb_component * nb_quad_per_elem,
nb_component * nb_quad_per_elem * sizeof(Real));
++new_size;
}
}
tmp.resize(new_size * nb_quad_per_elem);
vect.copy(tmp);
}
}
}
}
__END_AKANTU__
diff --git a/src/model/common/non_local_toolbox/non_local_manager.hh b/src/model/common/non_local_toolbox/non_local_manager.hh
index 1d6c047eb..0761cdd44 100644
--- a/src/model/common/non_local_toolbox/non_local_manager.hh
+++ b/src/model/common/non_local_toolbox/non_local_manager.hh
@@ -1,284 +1,288 @@
/**
* @file non_local_manager.hh
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Mon Sep 21 14:21:33 2015
+ *
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Classes that manages all the non-local neighborhoods
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_MANAGER_HH__
#define __AKANTU_NON_LOCAL_MANAGER_HH__
/* -------------------------------------------------------------------------- */
#include "aka_memory.hh"
#include "solid_mechanics_model.hh"
#include "non_local_neighborhood_base.hh"
#include "mesh_events.hh"
#include "parsable.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class NonLocalManager : public Memory,
public Parsable,
public MeshEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NonLocalManager(SolidMechanicsModel & model,
const ID & id = "non_local_manager",
const MemoryID & memory_id = 0);
virtual ~NonLocalManager();
typedef std::map<ID, NonLocalNeighborhoodBase *> NeighborhoodMap;
typedef std::pair<ID, ID> KeyCOO;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ----------------------------------------------------------------------- */
public:
/// initialize the non-local manager: compute pair lists and weights for all
/// neighborhoods
virtual void init();
/// insert new quadrature point in the grid
inline void insertQuad(const IntegrationPoint & quad,
const Vector<Real> & coords, const ID & neighborhood);
/// register non-local neighborhood
inline void registerNeighborhood(const ID & neighborhood,
const ID & weight_func_id);
/// associate a non-local variable to a neighborhood
void nonLocalVariableToNeighborhood(const ID & id, const ID & neighborhood);
/// return the fem object associated with a provided name
inline NonLocalNeighborhoodBase & getNeighborhood(const ID & name) const;
/// create the grid synchronizers for each neighborhood
void createNeighborhoodSynchronizers();
/// compute the weights in each neighborhood for non-local averaging
inline void computeWeights();
/// compute the weights in each neighborhood for non-local averaging
inline void updatePairLists();
/// register a new non-local material
inline void registerNonLocalMaterial(Material & new_mat);
/// register a non-local variable
inline void registerNonLocalVariable(const ID & variable_name,
const ID & nl_variable_name,
UInt nb_component);
/// average the non-local variables
void averageInternals(const GhostType & ghost_type = _not_ghost);
/// average the internals and compute the non-local stresses
virtual void computeAllNonLocalStresses();
/// register a new internal needed for the weight computations
inline ElementTypeMapReal &
registerWeightFunctionInternal(const ID & field_name);
/// update the flattened version of the weight function internals
inline void updateWeightFunctionInternals();
/// get Nb data for synchronization in parallel
inline UInt getNbDataForElements(const Array<Element> & elements,
const ID & id) const;
/// pack data for synchronization in parallel
inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag, const ID & id) const;
/// unpack data for synchronization in parallel
inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag, const ID & id) const;
protected:
/// create a new neighborhood for a given domain ID
void createNeighborhood(const ID & weight_func, const ID & neighborhood);
/// flatten the material internal fields needed for the non-local computations
void flattenInternal(ElementTypeMapReal & internal_flat,
const GhostType & ghost_type, const ElementKind & kind);
/// set the values of the jacobians
void setJacobians(const FEEngine & fe_engine, const ElementKind & kind);
/// allocation of eelment type maps
void initElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
const FEEngine & fe_engine,
const ElementKind el_kind = _ek_regular);
/// resizing of element type maps
void resizeElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
const FEEngine & fee,
const ElementKind el_kind = _ek_regular);
/// remove integration points from element type maps
void removeIntegrationPointsFromMap(
const ElementTypeMapArray<UInt> & new_numbering, UInt nb_component,
ElementTypeMapReal & element_map, const FEEngine & fee,
const ElementKind el_kind = _ek_regular);
/// allocate the non-local variables
void initNonLocalVariables();
/// copy the results of the averaging in the materials
void distributeInternals(ElementKind kind);
/// cleanup unneccessary ghosts
void cleanupExtraGhostElements(ElementTypeMap<UInt> & nb_ghost_protected);
/* ------------------------------------------------------------------------ */
/* MeshEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
virtual void onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event);
virtual void onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event);
virtual void onElementsChanged(__attribute__((unused)) const Array<Element> & old_elements_list,
__attribute__((unused)) const Array<Element> & new_elements_list,
__attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const ChangedElementsEvent & event) {};
virtual void onNodesAdded(__attribute__((unused)) const Array<UInt> & nodes_list,
__attribute__((unused)) const NewNodesEvent & event) {};
virtual void onNodesRemoved(__attribute__((unused)) const Array<UInt> & nodes_list,
__attribute__((unused)) const Array<UInt> & new_numbering,
__attribute__((unused)) const RemovedNodesEvent & event) {};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
AKANTU_GET_MACRO(Model, model, const SolidMechanicsModel &);
AKANTU_GET_MACRO_NOT_CONST(Volumes, volumes, ElementTypeMapReal &)
AKANTU_GET_MACRO(NbStressCalls, compute_stress_calls, UInt);
inline const Array<Real> & getJacobians(const ElementType & type,
const GhostType & ghost_type) {
return *jacobians(type, ghost_type);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the non-local neighborhoods present
NeighborhoodMap neighborhoods;
/// list of all the non-local materials in the model
std::vector<Material *> non_local_materials;
struct NonLocalVariable {
NonLocalVariable(const ID & variable_name, const ID & nl_variable_name,
const ID & id, UInt nb_component)
: local(variable_name, id), non_local(nl_variable_name, id),
nb_component(nb_component) {}
ElementTypeMapReal local;
ElementTypeMapReal non_local;
UInt nb_component;
};
/// the non-local variables associated to a certain neighborhood
std::map<ID, NonLocalVariable *> non_local_variables;
/// reference to the model
SolidMechanicsModel & model;
/// jacobians for all the elements in the mesh
ElementTypeMap<const Array<Real> *> jacobians;
/// store the position of the quadrature points
ElementTypeMapReal quad_positions;
/// store the volume of each quadrature point for the non-local weight
/// normalization
ElementTypeMapReal volumes;
/// the spatial dimension
const UInt spatial_dimension;
/// counter for computeStress calls
UInt compute_stress_calls;
/// map to store weight function types from input file
std::map<ID, ParserSection> weight_function_types;
/// map to store the internals needed by the weight functions
std::map<ID, ElementTypeMapReal *> weight_function_internals;
/* --------------------------------------------------------------------------
*/
/// the following are members needed to make this processor participate in the
/// grid creation of neighborhoods he doesn't own as a member. For details see
/// createGridSynchronizers function
/// synchronizer registry for dummy grid synchronizers
SynchronizerRegistry * dummy_registry;
/// map of dummy synchronizers
std::map<ID, GridSynchronizer *> dummy_synchronizers;
/// dummy spatial grid
SpatialGrid<IntegrationPoint> * dummy_grid;
/// create a set of all neighborhoods present in the simulation
std::set<ID> global_neighborhoods;
class DummyDataAccessor : public DataAccessor {
public:
virtual inline UInt getNbDataForElements(__attribute__((unused)) const Array<Element> & elements,
__attribute__((unused)) SynchronizationTag tag) const { return 0; };
virtual inline void packElementData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const Array<Element> & element,
__attribute__((unused)) SynchronizationTag tag) const {};
virtual inline void unpackElementData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const Array<Element> & element,
__attribute__((unused)) SynchronizationTag tag) {};
};
DummyDataAccessor dummy_accessor;
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "non_local_manager_inline_impl.cc"
#endif /* __AKANTU_NON_LOCAL_MANAGER_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc b/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc
index 11797e49f..be0ad72ca 100644
--- a/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc
+++ b/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc
@@ -1,234 +1,238 @@
/**
* @file non_local_manager_inline_impl.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Mon Sep 21 17:30:03 2015
+ *
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Nov 25 2015
*
* @brief inline implementation of non-local manager functions
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "grid_synchronizer.hh"
#include "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__
#define __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::insertQuad(const IntegrationPoint & quad, const Vector<Real> & coords, const ID & neighborhood) {
AKANTU_DEBUG_ASSERT(neighborhoods[neighborhood] != NULL,
"The neighborhood " << neighborhood << "has not been created");
neighborhoods[neighborhood]->insertQuad(quad, coords);
}
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::registerNeighborhood(const ID & neighborhood, const ID & weight_func_id) {
/// check if neighborhood has already been created
NeighborhoodMap::const_iterator it = neighborhoods.find(neighborhood);
if (it == neighborhoods.end()) {
this->createNeighborhood(weight_func_id, neighborhood);
}
}
/* -------------------------------------------------------------------------- */
inline NonLocalNeighborhoodBase & NonLocalManager::getNeighborhood(const ID & name) const{
AKANTU_DEBUG_IN();
NeighborhoodMap::const_iterator it = neighborhoods.find(name);
AKANTU_DEBUG_ASSERT(it != neighborhoods.end(),
"The neighborhood " << name << " is not registered");
AKANTU_DEBUG_OUT();
return *(it->second);
}
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::computeWeights() {
AKANTU_DEBUG_IN();
this->updateWeightFunctionInternals();
this->volumes.clear();
// NeighborhoodMap::iterator it = neighborhoods.begin();
// NeighborhoodMap::iterator end = neighborhoods.end();
// for (; it != end; ++it)
// it->second->updateWeights();
/// loop over all the neighborhoods and call onElementsRemoved
std::set<ID>::const_iterator global_neighborhood_it = global_neighborhoods.begin();
NeighborhoodMap::iterator it;
for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
it = neighborhoods.find(*global_neighborhood_it);
if (it != neighborhoods.end())
it->second->updateWeights();
else {
dummy_synchronizers[*global_neighborhood_it]->asynchronousSynchronize(dummy_accessor, _gst_mnl_weight);
dummy_synchronizers[*global_neighborhood_it]->waitEndSynchronize(dummy_accessor, _gst_mnl_weight);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::updatePairLists() {
AKANTU_DEBUG_IN();
/// compute the position of the quadrature points
this->model.getFEEngine().computeIntegrationPointsCoordinates(quad_positions);
NeighborhoodMap::iterator it = neighborhoods.begin();
NeighborhoodMap::iterator end = neighborhoods.end();
for (; it != end; ++it)
it->second->updatePairList();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::registerNonLocalVariable(const ID & variable_name, const ID & nl_variable_name, UInt nb_component) {
AKANTU_DEBUG_IN();
std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.find(variable_name);
if (non_local_variable_it == non_local_variables.end())
non_local_variables[nl_variable_name] = new NonLocalVariable(variable_name, nl_variable_name, this->id, nb_component);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::registerNonLocalMaterial(Material & new_mat) {
non_local_materials.push_back(&new_mat);
}
/* -------------------------------------------------------------------------- */
inline ElementTypeMapReal & NonLocalManager::registerWeightFunctionInternal(const ID & field_name) {
AKANTU_DEBUG_IN();
std::map<ID, ElementTypeMapReal *>::const_iterator it = this->weight_function_internals.find(field_name);
if (it == weight_function_internals.end()) {
weight_function_internals[field_name] = new ElementTypeMapReal(field_name, id);
}
return *(weight_function_internals[field_name]);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::updateWeightFunctionInternals() {
std::map<ID, ElementTypeMapReal *>::const_iterator it = this->weight_function_internals.begin();
std::map<ID, ElementTypeMapReal *>::const_iterator end = this->weight_function_internals.end();
for (; it != end; ++it) {
it->second->clear();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType ghost_type = (GhostType) g;
this->flattenInternal(*(it->second), ghost_type, _ek_regular);
}
}
}
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::nonLocalVariableToNeighborhood(const ID & variable_name, const ID & neighborhood) {
NeighborhoodMap::const_iterator it = neighborhoods.find(neighborhood);
AKANTU_DEBUG_ASSERT(it != neighborhoods.end(),
"The neighborhood " << neighborhood << " is not registered");
it->second->registerNonLocalVariable(variable_name);
}
/* -------------------------------------------------------------------------- */
inline UInt NonLocalManager::getNbDataForElements(const Array<Element> & elements,
const ID & id) const {
UInt size = 0;
UInt nb_quadrature_points = this->getModel().getNbIntegrationPoints(elements);
std::map<ID, NonLocalVariable *>::const_iterator it = non_local_variables.find(id);
AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
"The non-local variable " << id << " is not registered");
size += it->second->nb_component * sizeof(Real) * nb_quadrature_points;
return size;
}
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag,
const ID & id) const {
std::map<ID, NonLocalVariable *>::const_iterator it = non_local_variables.find(id);
AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
"The non-local variable " << id << " is not registered");
DataAccessor::packElementalDataHelper<Real>(it->second->local, buffer, elements, true,
this->model.getFEEngine());
}
/* -------------------------------------------------------------------------- */
inline void NonLocalManager::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag,
const ID & id) const {
std::map<ID, NonLocalVariable *>::const_iterator it = non_local_variables.find(id);
AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
"The non-local variable " << id << " is not registered");
DataAccessor::unpackElementalDataHelper<Real>(it->second->local, buffer, elements, true,
this->model.getFEEngine());
}
__END_AKANTU__
#endif /* __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood.hh b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
index 3ccb7dcc1..401b24f97 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
@@ -1,132 +1,136 @@
/**
* @file non_local_neighborhood.hh
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Sat Sep 26 18:29:59 2015
*
- * @brief Non-local neighborhood for non-local averaging based on
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Nov 25 2015
+ *
+ * @brief Non-local neighborhood for non-local averaging based on
* weight function
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_HH__
#define __AKANTU_NON_LOCAL_NEIGHBORHOOD_HH__
/* -------------------------------------------------------------------------- */
#include "base_weight_function.hh"
#include "non_local_neighborhood_base.hh"
#include "parsable.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class NonLocalManager;
class TestWeightFunction;
}
__BEGIN_AKANTU__
template<class WeightFunction = BaseWeightFunction>
class NonLocalNeighborhood : public NonLocalNeighborhoodBase {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NonLocalNeighborhood(NonLocalManager & manager,
const ElementTypeMapReal & quad_coordinates,
const ID & id = "neighborhood",
const MemoryID & memory_id = 0);
virtual ~NonLocalNeighborhood();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// compute the weights for non-local averaging
void computeWeights();
/// save the pair of weights in a file
void saveWeights(const std::string & filename) const;
/// compute the non-local counter part for a given element type map
virtual void weightedAverageOnNeighbours(const ElementTypeMapReal & to_accumulate,
ElementTypeMapReal & accumulated,
UInt nb_degree_of_freedom,
const GhostType & ghost_type2) const;
/// update the weights based on the weight function
void updateWeights();
/// register a new non-local variable in the neighborhood
virtual void registerNonLocalVariable(const ID & id);
protected:
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
/* -------------------------------------------------------------------------- */
/* Accessor */
/* -------------------------------------------------------------------------- */
AKANTU_GET_MACRO(NonLocalManager, *non_local_manager, const NonLocalManager &);
AKANTU_GET_MACRO_NOT_CONST(NonLocalManager, *non_local_manager, NonLocalManager &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// Pointer to non-local manager class
NonLocalManager * non_local_manager;
/// the weights associated to the pairs
Array<Real> * pair_weight[2];
/// weight function
WeightFunction * weight_function;
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* Implementation of template functions */
/* -------------------------------------------------------------------------- */
#include "non_local_neighborhood_tmpl.hh"
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "non_local_neighborhood_inline_impl.cc"
#endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc b/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
index b3bb7d761..ec6d58a8d 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
@@ -1,110 +1,113 @@
/**
* @file non_local_neighborhood_base.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Mon Sep 21 18:10:49 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
*
* @brief Implementation of non-local neighborhood base
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "non_local_neighborhood_base.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
NonLocalNeighborhoodBase::NonLocalNeighborhoodBase(const SolidMechanicsModel & model,
const ElementTypeMapReal & quad_coordinates,
const ID & id,
const MemoryID & memory_id) :
NeighborhoodBase(model, quad_coordinates, id, memory_id),
Parsable(_st_non_local, id) {
AKANTU_DEBUG_IN();
this->registerParam("radius" , neighborhood_radius , 100.,
_pat_parsable | _pat_readable , "Non local radius");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
NonLocalNeighborhoodBase::~NonLocalNeighborhoodBase() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NonLocalNeighborhoodBase::createGridSynchronizer() {
this->is_creating_grid = true;
std::set<SynchronizationTag> tags;
tags.insert(_gst_mnl_for_average);
tags.insert(_gst_mnl_weight);
std::stringstream sstr; sstr << getID() << ":grid_synchronizer";
this->grid_synchronizer = GridSynchronizer::createGridSynchronizer(this->model.getMesh(),
*spatial_grid,
sstr.str(),
synch_registry,
tags, 0, false);
this->is_creating_grid = false;
}
/* -------------------------------------------------------------------------- */
void NonLocalNeighborhoodBase::cleanupExtraGhostElements(std::set<Element> & relevant_ghost_elements) {
PairList::const_iterator first_pair = pair_list[_ghost].begin();
PairList::const_iterator last_pair = pair_list[_ghost].end();
for(;first_pair != last_pair; ++first_pair) {
const IntegrationPoint & q2 = first_pair->second;
relevant_ghost_elements.insert(q2);
}
Array<Element> ghosts_to_erase(0);
Mesh & mesh = this->model.getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
Element element;
element.ghost_type = _ghost;
std::set<Element>::const_iterator end = relevant_ghost_elements.end();
for(; it != last_type; ++it) {
element.type = *it;
UInt nb_ghost_elem = mesh.getNbElement(*it, _ghost);
for (UInt g = 0; g < nb_ghost_elem; ++g) {
element.element = g;
if (relevant_ghost_elements.find(element) == end) {
ghosts_to_erase.push_back(element);
}
}
}
/// remove the unneccessary ghosts from the synchronizer
this->grid_synchronizer->removeElements(ghosts_to_erase);
}
__END_AKANTU__
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh b/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
index 9d104308d..87a458104 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
@@ -1,122 +1,125 @@
/**
* @file non_local_neighborhood_base.hh
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Mon Sep 21 15:43:26 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
*
* @brief Non-local neighborhood base class
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
#define __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
/* -------------------------------------------------------------------------- */
#include "neighborhood_base.hh"
#include "parsable.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class NonLocalNeighborhoodBase : public NeighborhoodBase,
public Parsable{
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NonLocalNeighborhoodBase(const SolidMechanicsModel & model,
const ElementTypeMapReal & quad_coordinates,
const ID & id = "non_local_neighborhood",
const MemoryID & memory_id = 0);
virtual ~NonLocalNeighborhoodBase();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// create grid synchronizer and exchange ghost cells
virtual void createGridSynchronizer();
/// compute weights, for instance needed for non-local damage computation
virtual void computeWeights() {};
/// compute the non-local counter part for a given element type map
virtual void weightedAverageOnNeighbours(const ElementTypeMapReal & to_accumulate,
ElementTypeMapReal & accumulated,
UInt nb_degree_of_freedom,
const GhostType & ghost_type2) const {};
/// update the weights for the non-local averaging
virtual void updateWeights() {};
/// register a new non-local variable in the neighborhood
virtual void registerNonLocalVariable(const ID & id) {};
/// clean up the unneccessary ghosts
void cleanupExtraGhostElements(std::set<Element> & relevant_ghost_elements);
protected:
/// create the grid
void createGrid();
/* -------------------------------------------------------------------------- */
/* DataAccessor inherited members */
/* -------------------------------------------------------------------------- */
public:
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {return 0; };
virtual inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {};
virtual inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {};
/* -------------------------------------------------------------------------- */
/* Accessors */
/* -------------------------------------------------------------------------- */
public:
AKANTU_GET_MACRO(NonLocalVariables, non_local_variables, const std::set<ID> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// list of non-local variables associated to the neighborhood
std::set<ID> non_local_variables;
};
__END_AKANTU__
#endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc b/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
index 77b5640e3..636c2bcea 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
@@ -1,92 +1,95 @@
/**
* @file non_local_neighborhood_inline_impl.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Mon Oct 5 09:36:33 2015
+ *
+ * @date creation: Tue Oct 06 2015
+ * @date last modification: Wed Nov 25 2015
*
* @brief Implementation of inline functions of non-local neighborhood class
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_INLINE_IMPL_CC__
#define __AKANTU_NON_LOCAL_NEIGHBORHOOD_INLINE_IMPL_CC__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
inline UInt NonLocalNeighborhood<WeightFunction>::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
UInt size = 0;
if(tag == _gst_mnl_for_average) {
std::set<ID>::const_iterator it = non_local_variables.begin();
std::set<ID>::const_iterator end = non_local_variables.end();
for(;it != end; ++it) {
size += this->non_local_manager->getNbDataForElements(elements, *it);
}
}
size += this->weight_function->getNbDataForElements(elements, tag);
return size;
}
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
inline void NonLocalNeighborhood<WeightFunction>::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
if(tag == _gst_mnl_for_average) {
std::set<ID>::const_iterator it = non_local_variables.begin();
std::set<ID>::const_iterator end = non_local_variables.end();
for(;it != end; ++it) {
this->non_local_manager->packElementData(buffer, elements, tag, *it);
}
}
this->weight_function->packElementData(buffer, elements, tag);
}
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
inline void NonLocalNeighborhood<WeightFunction>::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
if(tag == _gst_mnl_for_average) {
std::set<ID>::const_iterator it = non_local_variables.begin();
std::set<ID>::const_iterator end = non_local_variables.end();
for(;it != end; ++it) {
this->non_local_manager->unpackElementData(buffer, elements, tag, *it);
}
}
this->weight_function->unpackElementData(buffer, elements, tag);
}
__END_AKANTU__
#endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
index 794755440..39af89d5d 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
@@ -1,283 +1,286 @@
/**
* @file non_local_neighborhood_tmpl.hh
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @date Sat Sep 26 18:43:30 2015
+ *
+ * @date creation: Mon Sep 28 2015
+ * @date last modification: Wed Nov 25 2015
*
* @brief Implementation of class non-local neighborhood
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "non_local_manager.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL_HH__
#define __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
NonLocalNeighborhood<WeightFunction>::NonLocalNeighborhood(NonLocalManager & manager,
const ElementTypeMapReal & quad_coordinates,
const ID & id,
const MemoryID & memory_id) :
NonLocalNeighborhoodBase(manager.getModel(), quad_coordinates, id, memory_id),
non_local_manager(&manager) {
AKANTU_DEBUG_IN();
for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type = (GhostType) gt;
pair_weight[ghost_type] = NULL;
}
this->weight_function = new WeightFunction(this->getNonLocalManager());
this->registerSubSection(_st_weight_function, "weight_parameter", *weight_function);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
NonLocalNeighborhood<WeightFunction>::~NonLocalNeighborhood() {
AKANTU_DEBUG_IN();
for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type = (GhostType) gt;
delete pair_weight[ghost_type];
}
delete weight_function;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
void NonLocalNeighborhood<WeightFunction>::computeWeights() {
AKANTU_DEBUG_IN();
this->weight_function->setRadius(this->neighborhood_radius);
Vector<Real> q1_coord(this->spatial_dimension);
Vector<Real> q2_coord(this->spatial_dimension);
UInt nb_weights_per_pair = 2; /// w1: q1->q2, w2: q2->q1
/// get the elementtypemap for the neighborhood volume for each quadrature point
ElementTypeMapReal & quadrature_points_volumes = this->non_local_manager->getVolumes();
/// update the internals of the weight function if applicable (not
/// all the weight functions have internals and do noting in that
/// case)
weight_function->updateInternals();
for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type = (GhostType) gt;
/// allocate the array to store the weight, if it doesn't exist already
if(!(pair_weight[ghost_type])) {
std::string ghost_id = "";
if (ghost_type == _ghost) ghost_id = ":ghost";
std::stringstream sstr; sstr << this->id <<":pair_weight:" << ghost_id;
pair_weight[ghost_type] = new Array<Real>(0, nb_weights_per_pair, sstr.str());
}
/// resize the array to the correct size
pair_weight[ghost_type]->resize(pair_list[ghost_type].size());
/// set entries to zero
pair_weight[ghost_type]->clear();
/// loop over all pairs in the current pair list array and their corresponding weights
PairList::const_iterator first_pair = pair_list[ghost_type].begin();
PairList::const_iterator last_pair = pair_list[ghost_type].end();
Array<Real>::vector_iterator weight_it = pair_weight[ghost_type]->begin(nb_weights_per_pair);
// Compute the weights
for(;first_pair != last_pair; ++first_pair, ++weight_it) {
Vector<Real> & weight = *weight_it;
const IntegrationPoint & q1 = first_pair->first;
const IntegrationPoint & q2 = first_pair->second;
/// get the coordinates for the given pair of quads
Array<Real>::const_vector_iterator coords_type_1_it = this->quad_coordinates(q1.type, q1.ghost_type).begin(this->spatial_dimension);
q1_coord = coords_type_1_it[q1.global_num];
Array<Real>::const_vector_iterator coords_type_2_it = this->quad_coordinates(q2.type, q2.ghost_type).begin(this->spatial_dimension);
q2_coord = coords_type_2_it[q2.global_num];
Array<Real> & quad_volumes_1 = quadrature_points_volumes(q1.type, q1.ghost_type);
const Array<Real> & jacobians_2 =
this->non_local_manager->getJacobians(q2.type, q2.ghost_type);
const Real & q2_wJ = jacobians_2(q2.global_num);
/// compute distance between the two quadrature points
Real r = q1_coord.distance(q2_coord);
/// compute the weight for averaging on q1 based on the distance
Real w1 = this->weight_function->operator()(r, q1, q2);
weight(0) = q2_wJ * w1;
quad_volumes_1(q1.global_num) += weight(0);
if(q2.ghost_type != _ghost && q1.global_num != q2.global_num) {
const Array<Real> & jacobians_1 =
this->non_local_manager->getJacobians(q1.type, q1.ghost_type);
Array<Real> & quad_volumes_2 =
quadrature_points_volumes(q2.type, q2.ghost_type);
/// compute the weight for averaging on q2
const Real & q1_wJ = jacobians_1(q1.global_num);
Real w2 = this->weight_function->operator()(r, q2, q1);
weight(1) = q1_wJ * w2;
quad_volumes_2(q2.global_num) += weight(1);
} else
weight(1) = 0.;
}
}
/// normalize the weights
for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type2 = (GhostType) gt;
PairList::const_iterator first_pair = pair_list[ghost_type2].begin();
PairList::const_iterator last_pair = pair_list[ghost_type2].end();
Array<Real>::vector_iterator weight_it = pair_weight[ghost_type2]->begin(nb_weights_per_pair);
// Compute the weights
for(;first_pair != last_pair; ++first_pair, ++weight_it) {
Vector<Real> & weight = *weight_it;
const IntegrationPoint & q1 = first_pair->first;
const IntegrationPoint & q2 = first_pair->second;
Array<Real> & quad_volumes_1 = quadrature_points_volumes(q1.type, q1.ghost_type);
Array<Real> & quad_volumes_2 = quadrature_points_volumes(q2.type, q2.ghost_type);
Real q1_volume = quad_volumes_1(q1.global_num);
weight(0) *= 1. / q1_volume;
if(ghost_type2 != _ghost) {
Real q2_volume = quad_volumes_2(q2.global_num);
weight(1) *= 1. / q2_volume;
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
void NonLocalNeighborhood<WeightFunction>::saveWeights(const std::string & filename) const {
std::ofstream pout;
std::stringstream sstr;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int prank = comm.whoAmI();
sstr << filename << "." << prank;
pout.open(sstr.str().c_str());
for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type = (GhostType) gt;
AKANTU_DEBUG_ASSERT((pair_weight[ghost_type]), "the weights have not been computed yet");
Array<Real> & weights = *(pair_weight[ghost_type]);
Array<Real>::const_vector_iterator weights_it = weights.begin(2);
for (UInt i = 0; i < weights.getSize(); ++i, ++weights_it)
pout << "w1: " << (*weights_it)(0) <<" w2: " << (*weights_it)(1) << std::endl;
}
}
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
void NonLocalNeighborhood<WeightFunction>::weightedAverageOnNeighbours(const ElementTypeMapReal & to_accumulate,
ElementTypeMapReal & accumulated,
UInt nb_degree_of_freedom,
const GhostType & ghost_type2) const {
AKANTU_DEBUG_IN();
std::set<ID>::iterator it = non_local_variables.find(accumulated.getName());
///do averaging only for variables registered in the neighborhood
if (it != non_local_variables.end()) {
PairList::const_iterator first_pair = pair_list[ghost_type2].begin();
PairList::const_iterator last_pair = pair_list[ghost_type2].end();
Array<Real>::vector_iterator weight_it = pair_weight[ghost_type2]->begin(2);
// Compute the weights
for(;first_pair != last_pair; ++first_pair, ++weight_it) {
Vector<Real> & weight = *weight_it;
const IntegrationPoint & q1 = first_pair->first;
const IntegrationPoint & q2 = first_pair->second;
const Array<Real> & to_acc_1 = to_accumulate(q1.type, q1.ghost_type);
Array<Real> & acc_1 = accumulated(q1.type, q1.ghost_type);
const Array<Real> & to_acc_2 = to_accumulate(q2.type, q2.ghost_type);
Array<Real> & acc_2 = accumulated(q2.type, q2.ghost_type);
for(UInt d = 0; d < nb_degree_of_freedom; ++d) {
acc_1(q1.global_num, d) += weight(0) * to_acc_2(q2.global_num, d);
}
if(ghost_type2 != _ghost) {
for(UInt d = 0; d < nb_degree_of_freedom; ++d) {
acc_2(q2.global_num, d) += weight(1) * to_acc_1(q1.global_num, d);
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
void NonLocalNeighborhood<WeightFunction>::updateWeights() {
// Update the weights for the non local variable averaging
if(this->weight_function->getUpdateRate() &&
(this->non_local_manager->getNbStressCalls() % this->weight_function->getUpdateRate() == 0)) {
this->synch_registry->asynchronousSynchronize(_gst_mnl_weight);
this->synch_registry->waitEndSynchronize(_gst_mnl_weight);
this->computeWeights();
}
}
/* -------------------------------------------------------------------------- */
template<class WeightFunction>
void NonLocalNeighborhood<WeightFunction>::registerNonLocalVariable(const ID & id) {
this->non_local_variables.insert(id);
}
__END_AKANTU__
#endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL__ */
diff --git a/src/model/heat_transfer/heat_transfer_model.cc b/src/model/heat_transfer/heat_transfer_model.cc
index 3eb41bb3d..3a695a664 100644
--- a/src/model/heat_transfer/heat_transfer_model.cc
+++ b/src/model/heat_transfer/heat_transfer_model.cc
@@ -1,1255 +1,1256 @@
/**
* @file heat_transfer_model.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Lucas Frerot <lucas.frerot@epfl.ch>
- * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Rui Wang <rui.wang@epfl.ch>
*
* @date creation: Sun May 01 2011
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Mon Nov 30 2015
*
* @brief Implementation of HeatTransferModel class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "heat_transfer_model.hh"
#include "group_manager_inline_impl.cc"
#include "dumpable_inline_impl.hh"
#include "aka_math.hh"
#include "aka_common.hh"
#include "fe_engine_template.hh"
#include "mesh.hh"
#include "static_communicator.hh"
#include "parser.hh"
#include "generalized_trapezoidal.hh"
#ifdef AKANTU_USE_MUMPS
#include "solver_mumps.hh"
#endif
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
# include "dumper_elemental_field.hh"
# include "dumper_element_partition.hh"
# include "dumper_internal_material_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const HeatTransferModelOptions default_heat_transfer_model_options(_explicit_lumped_capacity);
/* -------------------------------------------------------------------------- */
HeatTransferModel::HeatTransferModel(Mesh & mesh,
UInt dim,
const ID & id,
const MemoryID & memory_id) :
Model(mesh, dim, id, memory_id), Parsable(_st_heat, id),
integrator(NULL),
conductivity_matrix(NULL),
capacity_matrix(NULL),
jacobian_matrix(NULL),
temperature_gradient ("temperature_gradient", id),
temperature_on_qpoints ("temperature_on_qpoints", id),
conductivity_on_qpoints ("conductivity_on_qpoints", id),
k_gradt_on_qpoints ("k_gradt_on_qpoints", id),
int_bt_k_gT ("int_bt_k_gT", id),
bt_k_gT ("bt_k_gT", id),
conductivity(spatial_dimension, spatial_dimension),
thermal_energy ("thermal_energy", id),
solver(NULL),
pbc_synch(NULL) {
AKANTU_DEBUG_IN();
createSynchronizerRegistry(this);
std::stringstream sstr; sstr << id << ":fem";
registerFEEngineObject<MyFEEngineType>(sstr.str(), mesh,spatial_dimension);
this->temperature= NULL;
this->residual = NULL;
this->blocked_dofs = NULL;
#ifdef AKANTU_USE_IOHELPER
this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_regular);
#endif
this->registerParam("conductivity" , conductivity , _pat_parsmod);
this->registerParam("conductivity_variation", conductivity_variation, 0., _pat_parsmod);
this->registerParam("temperature_reference" , T_ref , 0., _pat_parsmod);
this->registerParam("capacity" , capacity , _pat_parsmod);
this->registerParam("density" , density , _pat_parsmod);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initModel() {
getFEEngine().initShapeFunctions(_not_ghost);
getFEEngine().initShapeFunctions(_ghost);
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initParallel(MeshPartition * partition,
DataAccessor * data_accessor) {
AKANTU_DEBUG_IN();
if (data_accessor == NULL) data_accessor = this;
Synchronizer & synch_parallel = createParallelSynch(partition,data_accessor);
synch_registry->registerSynchronizer(synch_parallel, _gst_htm_capacity);
synch_registry->registerSynchronizer(synch_parallel, _gst_htm_temperature);
synch_registry->registerSynchronizer(synch_parallel, _gst_htm_gradient_temperature);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initPBC() {
AKANTU_DEBUG_IN();
Model::initPBC();
pbc_synch = new PBCSynchronizer(pbc_pair);
synch_registry->registerSynchronizer(*pbc_synch, _gst_htm_capacity);
synch_registry->registerSynchronizer(*pbc_synch, _gst_htm_temperature);
changeLocalEquationNumberForPBC(pbc_pair,1);
// as long as there are ones on the diagonal of the matrix, we can put boudandary true for slaves
std::map<UInt, UInt>::iterator it = pbc_pair.begin();
std::map<UInt, UInt>::iterator end = pbc_pair.end();
while(it != end) {
(*blocked_dofs)((*it).first,0) = true;
++it;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initArrays() {
AKANTU_DEBUG_IN();
UInt nb_nodes = getFEEngine().getMesh().getNbNodes();
std::stringstream sstr_temp; sstr_temp << Model::id << ":temperature";
std::stringstream sstr_temp_rate; sstr_temp_rate << Model::id << ":temperature_rate";
std::stringstream sstr_inc; sstr_inc << Model::id << ":increment";
std::stringstream sstr_ext_flx; sstr_ext_flx << Model::id << ":external_flux";
std::stringstream sstr_residual; sstr_residual << Model::id << ":residual";
std::stringstream sstr_lump; sstr_lump << Model::id << ":lumped";
std::stringstream sstr_boun; sstr_boun << Model::id << ":blocked_dofs";
temperature = &(alloc<Real>(sstr_temp.str(), nb_nodes, 1, REAL_INIT_VALUE));
temperature_rate = &(alloc<Real>(sstr_temp_rate.str(), nb_nodes, 1, REAL_INIT_VALUE));
increment = &(alloc<Real>(sstr_inc.str(), nb_nodes, 1, REAL_INIT_VALUE));
external_heat_rate = &(alloc<Real>(sstr_ext_flx.str(), nb_nodes, 1, REAL_INIT_VALUE));
residual = &(alloc<Real>(sstr_residual.str(), nb_nodes, 1, REAL_INIT_VALUE));
capacity_lumped = &(alloc<Real>(sstr_lump.str(), nb_nodes, 1, REAL_INIT_VALUE));
blocked_dofs = &(alloc<bool>(sstr_boun.str(), nb_nodes, 1, false));
Mesh::ConnectivityTypeList::const_iterator it;
/* -------------------------------------------------------------------------- */
// byelementtype vectors
getFEEngine().getMesh().initElementTypeMapArray(temperature_on_qpoints,
1,
spatial_dimension);
getFEEngine().getMesh().initElementTypeMapArray(temperature_gradient,
spatial_dimension,
spatial_dimension);
getFEEngine().getMesh().initElementTypeMapArray(conductivity_on_qpoints,
spatial_dimension*spatial_dimension,
spatial_dimension);
getFEEngine().getMesh().initElementTypeMapArray(k_gradt_on_qpoints,
spatial_dimension,
spatial_dimension);
getFEEngine().getMesh().initElementTypeMapArray(bt_k_gT,
1,
spatial_dimension,
true);
getFEEngine().getMesh().initElementTypeMapArray(int_bt_k_gT,
1,
spatial_dimension,
true);
getFEEngine().getMesh().initElementTypeMapArray(thermal_energy,
1,
spatial_dimension);
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
const Mesh::ConnectivityTypeList & type_list =
getFEEngine().getMesh().getConnectivityTypeList(gt);
for(it = type_list.begin(); it != type_list.end(); ++it) {
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
UInt nb_element = getFEEngine().getMesh().getNbElement(*it, gt);
UInt nb_quad_points = this->getFEEngine().getNbIntegrationPoints(*it, gt) * nb_element;
temperature_on_qpoints(*it, gt).resize(nb_quad_points);
temperature_on_qpoints(*it, gt).clear();
temperature_gradient(*it, gt).resize(nb_quad_points);
temperature_gradient(*it, gt).clear();
conductivity_on_qpoints(*it, gt).resize(nb_quad_points);
conductivity_on_qpoints(*it, gt).clear();
k_gradt_on_qpoints(*it, gt).resize(nb_quad_points);
k_gradt_on_qpoints(*it, gt).clear();
bt_k_gT(*it, gt).resize(nb_quad_points);
bt_k_gT(*it, gt).clear();
int_bt_k_gT(*it, gt).resize(nb_element);
int_bt_k_gT(*it, gt).clear();
thermal_energy(*it, gt).resize(nb_element);
thermal_energy(*it, gt).clear();
}
}
/* -------------------------------------------------------------------------- */
dof_synchronizer = new DOFSynchronizer(getFEEngine().getMesh(),1);
dof_synchronizer->initLocalDOFEquationNumbers();
dof_synchronizer->initGlobalDOFEquationNumbers();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initSolver(__attribute__((unused)) SolverOptions & options) {
#if !defined(AKANTU_USE_MUMPS) // or other solver in the future \todo add AKANTU_HAS_SOLVER in CMake
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#else
UInt nb_global_nodes = mesh.getNbGlobalNodes();
delete jacobian_matrix;
std::stringstream sstr; sstr << Memory::id << ":jacobian_matrix";
jacobian_matrix = new SparseMatrix(nb_global_nodes, _symmetric, sstr.str(), memory_id);
jacobian_matrix->buildProfile(mesh, *dof_synchronizer, 1);
delete conductivity_matrix;
std::stringstream sstr_sti; sstr_sti << Memory::id << ":conductivity_matrix";
conductivity_matrix = new SparseMatrix(*jacobian_matrix, sstr_sti.str(), memory_id);
#ifdef AKANTU_USE_MUMPS
std::stringstream sstr_solv; sstr_solv << Memory::id << ":solver";
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
dof_synchronizer->initScatterGatherCommunicationScheme();
#else
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#endif //AKANTU_USE_MUMPS
if(solver)
solver->initialize(options);
#endif //AKANTU_HAS_SOLVER
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initImplicit(bool dynamic, SolverOptions & solver_options) {
AKANTU_DEBUG_IN();
method = dynamic ? _implicit_dynamic : _static;
initSolver(solver_options);
if(method == _implicit_dynamic) {
if(integrator) delete integrator;
integrator = new TrapezoidalRule1();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
HeatTransferModel::~HeatTransferModel()
{
AKANTU_DEBUG_IN();
if (integrator) delete integrator ;
if (conductivity_matrix) delete conductivity_matrix;
if (capacity_matrix) delete capacity_matrix ;
if (jacobian_matrix) delete jacobian_matrix ;
if (solver) delete solver ;
delete pbc_synch;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleCapacityLumped(const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
FEEngine & fem = getFEEngine();
const Mesh::ConnectivityTypeList & type_list
= fem.getMesh().getConnectivityTypeList(ghost_type);
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it)
{
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
UInt nb_element = getFEEngine().getMesh().getNbElement(*it,ghost_type);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(*it, ghost_type);
Array<Real> rho_1 (nb_element * nb_quadrature_points,1, capacity * density);
fem.assembleFieldLumped(rho_1,1,*capacity_lumped,
dof_synchronizer->getLocalDOFEquationNumbers(),
*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleCapacityLumped() {
AKANTU_DEBUG_IN();
capacity_lumped->clear();
assembleCapacityLumped(_not_ghost);
assembleCapacityLumped(_ghost);
getSynchronizerRegistry().synchronize(_gst_htm_capacity);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::updateResidual(bool compute_conductivity) {
AKANTU_DEBUG_IN();
/// @f$ r = q_{ext} - q_{int} - C \dot T @f$
// start synchronization
synch_registry->asynchronousSynchronize(_gst_htm_temperature);
// finalize communications
synch_registry->waitEndSynchronize(_gst_htm_temperature);
//clear the array
/// first @f$ r = q_{ext} @f$
// residual->clear();
residual->copy(*external_heat_rate);
/// then @f$ r -= q_{int} @f$
// update the not ghost ones
updateResidual(_not_ghost);
// update for the received ghosts
updateResidual(_ghost);
/* if (method == _explicit_lumped_capacity) {
this->solveExplicitLumped();
}*/
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleConductivityMatrix(bool compute_conductivity) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Assemble the new stiffness matrix.");
conductivity_matrix->clear();
switch(mesh.getSpatialDimension()) {
case 1: this->assembleConductivityMatrix<1>(_not_ghost,compute_conductivity); break;
case 2: this->assembleConductivityMatrix<2>(_not_ghost,compute_conductivity); break;
case 3: this->assembleConductivityMatrix<3>(_not_ghost,compute_conductivity); break;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void HeatTransferModel::assembleConductivityMatrix(const GhostType & ghost_type,bool compute_conductivity) {
AKANTU_DEBUG_IN();
Mesh & mesh = this->getFEEngine().getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
this->assembleConductivityMatrix<dim>(*it, ghost_type,compute_conductivity);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template <UInt dim>
void HeatTransferModel::assembleConductivityMatrix(const ElementType & type,
const GhostType & ghost_type,
bool compute_conductivity) {
AKANTU_DEBUG_IN();
SparseMatrix & K = *conductivity_matrix;
const Array<Real> & shapes_derivatives = this->getFEEngine().getShapesDerivatives(type, ghost_type);
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type, ghost_type);
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_d_b_size = nb_nodes_per_element;
Array<Real> * bt_d_b = new Array<Real>(nb_element * nb_quadrature_points,
bt_d_b_size * bt_d_b_size,
"B^t*D*B");
Matrix<Real> Bt_D(nb_nodes_per_element, dim);
Array<Real>::const_iterator< Matrix<Real> > shapes_derivatives_it = shapes_derivatives.begin(dim, nb_nodes_per_element);
Array<Real>::iterator< Matrix<Real> > Bt_D_B_it = bt_d_b->begin(bt_d_b_size, bt_d_b_size);
if (compute_conductivity)
this->computeConductivityOnQuadPoints(ghost_type);
Array<Real>::iterator< Matrix<Real> > D_it = conductivity_on_qpoints(type, ghost_type).begin(dim, dim);
Array<Real>::iterator< Matrix<Real> > D_end = conductivity_on_qpoints(type, ghost_type).end(dim, dim);
for (; D_it != D_end; ++D_it, ++Bt_D_B_it, ++shapes_derivatives_it) {
Matrix<Real> & D = *D_it;
const Matrix<Real> & B = *shapes_derivatives_it;
Matrix<Real> & Bt_D_B = *Bt_D_B_it;
Bt_D.mul<true, false>(B, D);
Bt_D_B.mul<false, false>(Bt_D, B);
}
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e = new Array<Real>(nb_element,
bt_d_b_size * bt_d_b_size,
"K_e");
this->getFEEngine().integrate(*bt_d_b, *K_e,
bt_d_b_size * bt_d_b_size,
type, ghost_type);
delete bt_d_b;
this->getFEEngine().assembleMatrix(*K_e, K, 1, type, ghost_type);
delete K_e;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::updateResidualInternal() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Update the residual");
// f = q_ext - q_int - Mddot = q - Mddot;
if(method != _static) {
// f -= Mddot
if(capacity_matrix) {
// if full mass_matrix
Array<Real> * Mddot = new Array<Real>(*temperature_rate, true, "Mddot");
*Mddot *= *capacity_matrix;
*residual -= *Mddot;
delete Mddot;
} else if (capacity_lumped) {
// else lumped mass
UInt nb_nodes = temperature_rate->getSize();
UInt nb_degree_of_freedom = temperature_rate->getNbComponent();
Real * capacity_val = capacity_lumped->storage();
Real * temp_rate_val = temperature_rate->storage();
Real * res_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*res_val -= *temp_rate_val * *capacity_val;
}
blocked_dofs_val++;
res_val++;
capacity_val++;
temp_rate_val++;
}
} else {
AKANTU_DEBUG_ERROR("No function called to assemble the mass matrix.");
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::solveStatic() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Solving Ku = f");
AKANTU_DEBUG_ASSERT(conductivity_matrix != NULL,
"You should first initialize the implicit solver and assemble the stiffness matrix");
UInt nb_nodes = temperature->getSize();
UInt nb_degree_of_freedom = temperature->getNbComponent() * nb_nodes;
jacobian_matrix->copyContent(*conductivity_matrix);
jacobian_matrix->applyBoundary(*blocked_dofs);
increment->clear();
solver->setRHS(*residual);
solver->factorize();
solver->solve(*increment);
Real * increment_val = increment->storage();
Real * temperature_val = temperature->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt j = 0; j < nb_degree_of_freedom;
++j, ++temperature_val, ++increment_val, ++blocked_dofs_val) {
if (!(*blocked_dofs_val)) {
*temperature_val += *increment_val;
}
else {
*increment_val = 0.0;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::computeConductivityOnQuadPoints(const GhostType & ghost_type) {
const Mesh::ConnectivityTypeList & type_list =
this->getFEEngine().getMesh().getConnectivityTypeList(ghost_type);
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it) {
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
Array<Real> & temperature_interpolated = temperature_on_qpoints(*it, ghost_type);
//compute the temperature on quadrature points
this->getFEEngine().interpolateOnIntegrationPoints(*temperature,
temperature_interpolated,
1 ,*it,ghost_type);
Array<Real>::matrix_iterator C_it =
conductivity_on_qpoints(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator C_end =
conductivity_on_qpoints(*it, ghost_type).end(spatial_dimension, spatial_dimension);
Array<Real>::iterator<Real> T_it = temperature_interpolated.begin();
for (;C_it != C_end; ++C_it, ++T_it) {
Matrix<Real> & C = *C_it;
Real & T = *T_it;
C = conductivity;
Matrix<Real> variation(spatial_dimension, spatial_dimension, conductivity_variation * (T - T_ref));
C += conductivity_variation;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::computeKgradT(const GhostType & ghost_type,bool compute_conductivity) {
if (compute_conductivity)
computeConductivityOnQuadPoints(ghost_type);
const Mesh::ConnectivityTypeList & type_list =
this->getFEEngine().getMesh().getConnectivityTypeList(ghost_type);
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it) {
const ElementType & type = *it;
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
Array<Real> & gradient = temperature_gradient(*it, ghost_type);
this->getFEEngine().gradientOnIntegrationPoints(*temperature,
gradient,
1 ,*it, ghost_type);
Array<Real>::matrix_iterator C_it =
conductivity_on_qpoints(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::vector_iterator BT_it = gradient.begin(spatial_dimension);
Array<Real>::vector_iterator k_BT_it =
k_gradt_on_qpoints(type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator k_BT_end =
k_gradt_on_qpoints(type, ghost_type).end(spatial_dimension);
for (;k_BT_it != k_BT_end; ++k_BT_it, ++BT_it, ++C_it) {
Vector<Real> & k_BT = *k_BT_it;
Vector<Real> & BT = *BT_it;
Matrix<Real> & C = *C_it;
k_BT.mul<false>(C, BT);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::updateResidual(const GhostType & ghost_type, bool compute_conductivity) {
AKANTU_DEBUG_IN();
const Mesh::ConnectivityTypeList & type_list =
this->getFEEngine().getMesh().getConnectivityTypeList(ghost_type);
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it) {
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
Array<Real> & shapes_derivatives =
const_cast<Array<Real> &>(getFEEngine().getShapesDerivatives(*it,ghost_type));
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
// compute k \grad T
computeKgradT(ghost_type,compute_conductivity);
Array<Real>::vector_iterator k_BT_it =
k_gradt_on_qpoints(*it,ghost_type).begin(spatial_dimension);
Array<Real>::matrix_iterator B_it =
shapes_derivatives.begin(spatial_dimension, nb_nodes_per_element);
Array<Real>::vector_iterator Bt_k_BT_it =
bt_k_gT(*it,ghost_type).begin(nb_nodes_per_element);
Array<Real>::vector_iterator Bt_k_BT_end =
bt_k_gT(*it,ghost_type).end(nb_nodes_per_element);
for (;Bt_k_BT_it != Bt_k_BT_end; ++Bt_k_BT_it, ++B_it, ++k_BT_it) {
Vector<Real> & k_BT = *k_BT_it;
Vector<Real> & Bt_k_BT = *Bt_k_BT_it;
Matrix<Real> & B = *B_it;
Bt_k_BT.mul<true>(B, k_BT);
}
this->getFEEngine().integrate(bt_k_gT(*it,ghost_type),
int_bt_k_gT(*it,ghost_type),
nb_nodes_per_element, *it,ghost_type);
this->getFEEngine().assembleArray(int_bt_k_gT(*it,ghost_type), *residual,
dof_synchronizer->getLocalDOFEquationNumbers(),
1, *it,ghost_type, empty_filter, -1);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::solveExplicitLumped() {
AKANTU_DEBUG_IN();
/// finally @f$ r -= C \dot T @f$
// lumped C
UInt nb_nodes = temperature_rate->getSize();
UInt nb_degree_of_freedom = temperature_rate->getNbComponent();
Real * capacity_val = capacity_lumped->storage();
Real * temp_rate_val = temperature_rate->storage();
Real * res_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*res_val -= *capacity_val * *temp_rate_val;
}
blocked_dofs_val++;
res_val++;
capacity_val++;
temp_rate_val++;
}
#ifndef AKANTU_NDEBUG
getSynchronizerRegistry().synchronize(akantu::_gst_htm_gradient_temperature);
#endif
capacity_val = capacity_lumped->storage();
res_val = residual->storage();
blocked_dofs_val = blocked_dofs->storage();
Real * inc = increment->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*inc = (*res_val / *capacity_val);
}
res_val++;
blocked_dofs_val++;
inc++;
capacity_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::explicitPred() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(integrator, "integrator was not instanciated");
integrator->integrationSchemePred(time_step,
*temperature,
*temperature_rate,
*blocked_dofs);
UInt nb_nodes = temperature->getSize();
UInt nb_degree_of_freedom = temperature->getNbComponent();
Real * temp = temperature->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n, ++temp)
if(*temp < 0.) *temp = 0.;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::explicitCorr() {
AKANTU_DEBUG_IN();
integrator->integrationSchemeCorrTempRate(time_step,
*temperature,
*temperature_rate,
*blocked_dofs,
*increment);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::implicitPred(){
AKANTU_DEBUG_IN();
if(method == _implicit_dynamic)
integrator->integrationSchemePred(time_step,
*temperature,
*temperature_rate,
*blocked_dofs);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::implicitCorr(){
AKANTU_DEBUG_IN();
if(method == _implicit_dynamic) {
integrator->integrationSchemeCorrTemp(time_step,
*temperature,
*temperature_rate,
*blocked_dofs,
*increment);
} else {
UInt nb_nodes = temperature->getSize();
UInt nb_degree_of_freedom = temperature->getNbComponent() * nb_nodes;
Real * incr_val = increment->storage();
Real * temp_val = temperature->storage();
bool * boun_val = blocked_dofs->storage();
for (UInt j = 0; j < nb_degree_of_freedom; ++j, ++temp_val, ++incr_val, ++boun_val){
*incr_val *= (1. - *boun_val);
*temp_val += *incr_val;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getStableTimeStep()
{
AKANTU_DEBUG_IN();
Real el_size;
Real min_el_size = std::numeric_limits<Real>::max();
Real conductivitymax = conductivity(0, 0);
//get the biggest parameter from k11 until k33//
for(UInt i = 0; i < spatial_dimension; i++)
for(UInt j = 0; j < spatial_dimension; j++)
conductivitymax = std::max(conductivity(i, j), conductivitymax);
const Mesh::ConnectivityTypeList & type_list =
getFEEngine().getMesh().getConnectivityTypeList();
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it) {
if(getFEEngine().getMesh().getSpatialDimension(*it) != spatial_dimension)
continue;
UInt nb_nodes_per_element = getFEEngine().getMesh().getNbNodesPerElement(*it);
Array<Real> coord(0, nb_nodes_per_element*spatial_dimension);
FEEngine::extractNodalToElementField(getFEEngine().getMesh(), getFEEngine().getMesh().getNodes(),
coord, *it, _not_ghost);
Array<Real>::matrix_iterator el_coord = coord.begin(spatial_dimension, nb_nodes_per_element);
UInt nb_element = getFEEngine().getMesh().getNbElement(*it);
for (UInt el = 0; el < nb_element; ++el, ++el_coord) {
el_size = getFEEngine().getElementInradius(*el_coord, *it);
min_el_size = std::min(min_el_size, el_size);
}
AKANTU_DEBUG_INFO("The minimum element size : " << min_el_size
<< " and the max conductivity is : "
<< conductivitymax);
}
Real min_dt = 2 * min_el_size * min_el_size * density
* capacity / conductivitymax;
StaticCommunicator::getStaticCommunicator().allReduce(&min_dt, 1, _so_min);
AKANTU_DEBUG_OUT();
return min_dt;
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::readMaterials() {
std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
sub_sect = this->parser->getSubSections(_st_heat);
Parser::const_section_iterator it = sub_sect.first;
const ParserSection & section = *it;
this->parseSection(section);
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initFull(const ModelOptions & options){
Model::initFull(options);
readMaterials();
const HeatTransferModelOptions & my_options
= dynamic_cast<const HeatTransferModelOptions &>(options);
method = my_options.analysis_method;
//initialize the vectors
initArrays();
temperature->clear();
temperature_rate->clear();
external_heat_rate->clear();
// initialize pbc
if(pbc_pair.size()!=0)
initPBC();
if (method == _explicit_lumped_capacity){
integrator = new ForwardEuler();
}
if (method == _implicit_dynamic) {
initImplicit(true);
}
if (method == _static) {
initImplicit(false);
}
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleCapacity() {
AKANTU_DEBUG_IN();
if(!capacity_matrix) {
std::stringstream sstr; sstr << id << ":capacity_matrix";
capacity_matrix = new SparseMatrix(*jacobian_matrix, sstr.str(), memory_id);
}
assembleCapacity(_not_ghost);
// assembleMass(_ghost);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleCapacity(GhostType ghost_type) {
AKANTU_DEBUG_IN();
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
Array<Real> rho_1(0,1);
//UInt nb_element;
capacity_matrix->clear();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
computeRho(rho_1, type, ghost_type);
fem.assembleFieldMatrix(rho_1, 1, *capacity_matrix, type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::computeRho(Array<Real> & rho,
ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
FEEngine & fem = this->getFEEngine();
UInt nb_element = fem.getMesh().getNbElement(type,ghost_type);
UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
rho.resize(nb_element * nb_quadrature_points);
Real * rho_1_val = rho.storage();
/// compute @f$ rho @f$ for each nodes of each element
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_quadrature_points; ++n) {
*rho_1_val++ = this->capacity;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
bool HeatTransferModel::testConvergence<_scc_increment>(Real tolerance, Real & error){
AKANTU_DEBUG_IN();
UInt nb_nodes = temperature->getSize();
UInt nb_degree_of_freedom = temperature->getNbComponent();
error = 0;
Real norm[2] = {0., 0.};
Real * increment_val = increment->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
Real * temperature_val = temperature->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val) && is_local_node) {
norm[0] += *increment_val * *increment_val;
norm[1] += *temperature_val * *temperature_val;
}
blocked_dofs_val++;
increment_val++;
temperature_val++;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(norm, 2, _so_sum);
norm[0] = sqrt(norm[0]);
norm[1] = sqrt(norm[1]);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm[0]), "Something goes wrong in the solve phase");
if (norm[1] < Math::getTolerance()) {
error = norm[0];
AKANTU_DEBUG_OUT();
// cout<<"Error 1: "<<error<<endl;
return error < tolerance;
}
AKANTU_DEBUG_OUT();
if(norm[1] > Math::getTolerance())
error = norm[0] / norm[1];
else
error = norm[0]; //In case the total displacement is zero!
// cout<<"Error 2: "<<error<<endl;
return (error < tolerance);
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initFEEngineBoundary(bool create_surface) {
if(create_surface)
MeshUtils::buildFacets(getFEEngine().getMesh());
FEEngine & fem_boundary = getFEEngineBoundary();
fem_boundary.initShapeFunctions();
fem_boundary.computeNormalsOnIntegrationPoints();
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::computeThermalEnergyByNode() {
AKANTU_DEBUG_IN();
Real ethermal = 0.;
Array<Real>::vector_iterator heat_rate_it =
residual->begin(residual->getNbComponent());
Array<Real>::vector_iterator heat_rate_end =
residual->end(residual->getNbComponent());
UInt n = 0;
for(;heat_rate_it != heat_rate_end; ++heat_rate_it, ++n) {
Real heat = 0;
bool is_local_node = mesh.isLocalOrMasterNode(n);
bool is_not_pbc_slave_node = !isPBCSlaveNode(n);
bool count_node = is_local_node && is_not_pbc_slave_node;
Vector<Real> & heat_rate = *heat_rate_it;
for (UInt i = 0; i < heat_rate.size(); ++i) {
if (count_node)
heat += heat_rate[i] * time_step;
}
ethermal += heat;
}
StaticCommunicator::getStaticCommunicator().allReduce(&ethermal, 1, _so_sum);
AKANTU_DEBUG_OUT();
return ethermal;
}
/* -------------------------------------------------------------------------- */
template<class iterator>
void HeatTransferModel::getThermalEnergy(iterator Eth,
Array<Real>::const_iterator<Real> T_it,
Array<Real>::const_iterator<Real> T_end) const {
for(;T_it != T_end; ++T_it, ++Eth) {
*Eth = capacity * density * *T_it;
}
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getThermalEnergy(const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
Vector<Real> Eth_on_quarature_points(nb_quadrature_points);
Array<Real>::iterator<Real> T_it = this->temperature_on_qpoints(type).begin();
T_it += index * nb_quadrature_points;
Array<Real>::iterator<Real> T_end = T_it + nb_quadrature_points;
getThermalEnergy(Eth_on_quarature_points.storage(), T_it, T_end);
return getFEEngine().integrate(Eth_on_quarature_points, type, index);
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getThermalEnergy() {
Real Eth = 0;
Mesh & mesh = getFEEngine().getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension);
for(; it != last_type; ++it) {
UInt nb_element = getFEEngine().getMesh().getNbElement(*it, _not_ghost);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(*it, _not_ghost);
Array<Real> Eth_per_quad(nb_element * nb_quadrature_points, 1);
Array<Real>::iterator<Real> T_it = this->temperature_on_qpoints(*it).begin();
Array<Real>::iterator<Real> T_end = this->temperature_on_qpoints(*it).end();
getThermalEnergy(Eth_per_quad.begin(), T_it, T_end);
Eth += getFEEngine().integrate(Eth_per_quad, *it);
}
return Eth;
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getEnergy(const std::string & id) {
AKANTU_DEBUG_IN();
Real energy = 0;
if("thermal") energy = getThermalEnergy();
// reduction sum over all processors
StaticCommunicator::getStaticCommunicator().allReduce(&energy, 1, _so_sum);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getEnergy(const std::string & energy_id, const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
Real energy = 0.;
if("thermal") energy = getThermalEnergy(type, index);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
dumper::Field * HeatTransferModel::createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
std::map<std::string,Array<bool>* > uint_nodal_fields;
uint_nodal_fields["blocked_dofs" ] = blocked_dofs;
dumper::Field * field = NULL;
field = mesh.createNodalField(uint_nodal_fields[field_name],group_name);
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
std::map<std::string,Array<Real>* > real_nodal_fields;
real_nodal_fields["temperature" ] = temperature;
real_nodal_fields["temperature_rate" ] = temperature_rate;
real_nodal_fields["external_heat_rate" ] = external_heat_rate;
real_nodal_fields["residual" ] = residual;
real_nodal_fields["capacity_lumped" ] = capacity_lumped;
real_nodal_fields["increment" ] = increment;
dumper::Field * field =
mesh.createNodalField(real_nodal_fields[field_name],group_name);
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel
::createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const UInt & spatial_dimension,
const ElementKind & element_kind){
dumper::Field * field = NULL;
if(field_name == "partitions")
field = mesh.createElementalField<UInt, dumper::ElementPartitionField>(mesh.getConnectivities(),group_name,this->spatial_dimension,element_kind);
else if(field_name == "temperature_gradient"){
ElementTypeMap<UInt> nb_data_per_elem = this->mesh.getNbDataPerElem(temperature_gradient,element_kind);
field =
mesh.createElementalField<Real,
dumper::InternalMaterialField>(temperature_gradient,
group_name,
this->spatial_dimension,
element_kind,
nb_data_per_elem);
}
else if(field_name == "conductivity"){
ElementTypeMap<UInt> nb_data_per_elem = this->mesh.getNbDataPerElem(conductivity_on_qpoints,element_kind);
field =
mesh.createElementalField<Real,
dumper::InternalMaterialField>(conductivity_on_qpoints,
group_name,
this->spatial_dimension,
element_kind,
nb_data_per_elem);
}
return field;
}
/* -------------------------------------------------------------------------- */
#else
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel
::createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const ElementKind & element_kind){
return NULL;
}
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel::createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
return NULL;
}
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
return NULL;
}
#endif
__END_AKANTU__
diff --git a/src/model/heat_transfer/heat_transfer_model.hh b/src/model/heat_transfer/heat_transfer_model.hh
index b84341028..c32e85634 100644
--- a/src/model/heat_transfer/heat_transfer_model.hh
+++ b/src/model/heat_transfer/heat_transfer_model.hh
@@ -1,455 +1,456 @@
/**
* @file heat_transfer_model.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
- * @author Rui Wang <rui.wang@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Rui Wang <rui.wang@epfl.ch>
*
* @date creation: Sun May 01 2011
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief Model of Heat Transfer
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_HEAT_TRANSFER_MODEL_HH__
#define __AKANTU_HEAT_TRANSFER_MODEL_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_types.hh"
#include "aka_voigthelper.hh"
#include "aka_memory.hh"
#include "model.hh"
#include "integrator_gauss.hh"
#include "shape_lagrange.hh"
#include "dumpable.hh"
#include "parsable.hh"
#include "solver.hh"
#include "generalized_trapezoidal.hh"
namespace akantu {
class IntegrationScheme1stOrder;
}
__BEGIN_AKANTU__
struct HeatTransferModelOptions : public ModelOptions {
HeatTransferModelOptions(AnalysisMethod analysis_method = _explicit_lumped_capacity ) : analysis_method(analysis_method) {}
AnalysisMethod analysis_method;
};
extern const HeatTransferModelOptions default_heat_transfer_model_options;
class HeatTransferModel : public Model, public DataAccessor, public Parsable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef FEEngineTemplate<IntegratorGauss,ShapeLagrange> MyFEEngineType;
HeatTransferModel(Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "heat_transfer_model",
const MemoryID & memory_id = 0);
virtual ~HeatTransferModel() ;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// generic function to initialize everything ready for explicit dynamics
void initFull(const ModelOptions & options = default_heat_transfer_model_options);
/// initialize the fem object of the boundary
void initFEEngineBoundary(bool create_surface = true);
/// read one material file to instantiate all the materials
void readMaterials();
/// allocate all vectors
void initArrays();
/// register the tags associated with the parallel synchronizer
void initParallel(MeshPartition * partition, DataAccessor * data_accessor=NULL);
/// initialize the model
void initModel();
/// init PBC synchronizer
void initPBC();
/// initialize the solver and the jacobian_matrix (called by initImplicit)
void initSolver(SolverOptions & solver_options);
/// initialize the stuff for the implicit solver
void initImplicit(bool dynamic, SolverOptions & solver_options = _solver_no_options);
/// function to print the contain of the class
virtual void printself(__attribute__ ((unused)) std::ostream & stream,
__attribute__ ((unused)) int indent = 0) const {};
/* ------------------------------------------------------------------------ */
/* Methods for explicit */
/* ------------------------------------------------------------------------ */
public:
/// compute and get the stable time step
Real getStableTimeStep();
/// compute the heat flux
void updateResidual(bool compute_conductivity = false);
/// calculate the lumped capacity vector for heat transfer problem
void assembleCapacityLumped();
/// update the temperature from the temperature rate
void explicitPred();
/// update the temperature rate from the increment
void explicitCorr();
/// implicit time integration predictor
void implicitPred();
/// implicit time integration corrector
void implicitCorr();
/// solve the system in temperature rate @f$C\delta \dot T = q_{n+1} - C \dot T_{n}@f$
/// this function needs to be run for dynamics
void solveExplicitLumped();
// /// initialize the heat flux
// void initializeResidual(Array<Real> &temp);
// /// initialize temperature
// void initializeTemperature(Array<Real> &temp);
/* ------------------------------------------------------------------------ */
/* Methods for implicit */
/* ------------------------------------------------------------------------ */
public:
/**
* solve Kt = q
**/
void solveStatic();
/// test if the system is converged
template <SolveConvergenceCriteria criteria>
bool testConvergence(Real tolerance, Real & error);
/**
* solve a step (predictor + convergence loop + corrector) using the
* the given convergence method (see akantu::SolveConvergenceMethod)
* and the given convergence criteria (see
* akantu::SolveConvergenceCriteria)
**/
template <SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance, UInt max_iteration = 100);
template <SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance,
Real & error,
UInt max_iteration = 100,
bool do_not_factorize = false);
/// assemble the conductivity matrix
void assembleConductivityMatrix(bool compute_conductivity = true);
/// assemble the conductivity matrix
void assembleCapacity();
/// assemble the conductivity matrix
void assembleCapacity(GhostType ghost_type);
/// compute the capacity on quadrature points
void computeRho(Array<Real> & rho, ElementType type,
GhostType ghost_type);
protected:
/// compute A and solve @f[ A\delta u = f_ext - f_int @f]
template <GeneralizedTrapezoidal::IntegrationSchemeCorrectorType type>
void solve(Array<Real> &increment, Real block_val = 1.,
bool need_factorize = true, bool has_profile_changed = false);
/// computation of the residual for the convergence loop
void updateResidualInternal();
private:
/// compute the heat flux on ghost types
void updateResidual(const GhostType & ghost_type, bool compute_conductivity = false);
/// calculate the lumped capacity vector for heat transfer problem (w ghosttype)
void assembleCapacityLumped(const GhostType & ghost_type);
/// assemble the conductivity matrix (w/ ghost type)
template <UInt dim>
void assembleConductivityMatrix(const GhostType & ghost_type,
bool compute_conductivity = true);
/// assemble the conductivity matrix
template <UInt dim>
void assembleConductivityMatrix(const ElementType & type,
const GhostType & ghost_type,
bool compute_conductivity = true);
/// compute the conductivity tensor for each quadrature point in an array
void computeConductivityOnQuadPoints(const GhostType & ghost_type);
/// compute vector k \grad T for each quadrature point
void computeKgradT(const GhostType & ghost_type,bool compute_conductivity);
/// compute the thermal energy
Real computeThermalEnergyByNode();
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
inline UInt getNbDataToPack(SynchronizationTag tag) const;
inline UInt getNbDataToUnpack(SynchronizationTag tag) const;
inline void packData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag) const;
inline void unpackData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Dumpable interface */
/* ------------------------------------------------------------------------ */
public:
virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field * createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const UInt & spatial_dimension,
const ElementKind & kind);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
inline FEEngine & getFEEngineBoundary(const std::string & name = "");
AKANTU_GET_MACRO(Density, density, Real);
AKANTU_GET_MACRO(Capacity, capacity, Real);
/// get the dimension of the system space
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// get the current value of the time step
AKANTU_GET_MACRO(TimeStep, time_step, Real);
/// set the value of the time step
AKANTU_SET_MACRO(TimeStep, time_step, Real);
/// get the assembled heat flux
AKANTU_GET_MACRO(Residual, *residual, Array<Real>&);
/// get the lumped capacity
AKANTU_GET_MACRO(CapacityLumped, *capacity_lumped, Array<Real>&);
/// get the boundary vector
AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool>&);
/// get conductivity matrix
AKANTU_GET_MACRO(ConductivityMatrix, *conductivity_matrix, const SparseMatrix&);
/// get the external heat rate vector
AKANTU_GET_MACRO(ExternalHeatRate, *external_heat_rate, Array<Real>&);
/// get the temperature gradient
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(TemperatureGradient, temperature_gradient, Real);
/// get the conductivity on q points
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ConductivityOnQpoints, conductivity_on_qpoints, Real);
/// get the conductivity on q points
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(TemperatureOnQpoints, temperature_on_qpoints, Real);
/// internal variables
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(KGradtOnQpoints, k_gradt_on_qpoints, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(IntBtKgT, int_bt_k_gT, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(BtKgT, bt_k_gT, Real);
/// get the temperature
AKANTU_GET_MACRO(Temperature, *temperature, Array<Real> &);
/// get the temperature derivative
AKANTU_GET_MACRO(TemperatureRate, *temperature_rate, Array<Real> &);
/// get the equation number Array<Int>
AKANTU_GET_MACRO(EquationNumber, *equation_number, const Array<Int> &);
/// get the energy denominated by thermal
Real getEnergy(const std::string & energy_id, const ElementType & type, UInt index);
/// get the energy denominated by thermal
Real getEnergy(const std::string & energy_id);
/// get the thermal energy for a given element
Real getThermalEnergy(const ElementType & type, UInt index);
/// get the thermal energy for a given element
Real getThermalEnergy();
protected:
/* ----------------------------------------------------------------------- */
template<class iterator>
void getThermalEnergy(iterator Eth,
Array<Real>::const_iterator<Real> T_it,
Array<Real>::const_iterator<Real> T_end) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// number of iterations
UInt n_iter;
IntegrationScheme1stOrder * integrator;
/// time step
Real time_step;
/// temperatures array
Array<Real> * temperature;
/// temperatures derivatives array
Array<Real> * temperature_rate;
/// increment array (@f$\delta \dot T@f$ or @f$\delta T@f$)
Array<Real> * increment;
/// conductivity matrix
SparseMatrix * conductivity_matrix;
/// capacity matrix
SparseMatrix *capacity_matrix;
/// jacobian matrix
SparseMatrix * jacobian_matrix;
/// the density
Real density;
/// the speed of the changing temperature
ElementTypeMapArray<Real> temperature_gradient;
/// temperature field on quadrature points
ElementTypeMapArray<Real> temperature_on_qpoints;
/// conductivity tensor on quadrature points
ElementTypeMapArray<Real> conductivity_on_qpoints;
/// vector k \grad T on quad points
ElementTypeMapArray<Real> k_gradt_on_qpoints;
/// vector \int \grad N k \grad T
ElementTypeMapArray<Real> int_bt_k_gT;
/// vector \grad N k \grad T
ElementTypeMapArray<Real> bt_k_gT;
/// external flux vector
Array<Real> * external_heat_rate;
/// residuals array
Array<Real> * residual;
/// position of a dof in the K matrix
Array<Int> * equation_number;
//lumped vector
Array<Real> * capacity_lumped;
/// boundary vector
Array<bool> * blocked_dofs;
//realtime
Real time;
///capacity
Real capacity;
//conductivity matrix
Matrix<Real> conductivity;
//linear variation of the conductivity (for temperature dependent conductivity)
Real conductivity_variation;
// reference temperature for the interpretation of temperature variation
Real T_ref;
//the biggest parameter of conductivity matrix
Real conductivitymax;
/// thermal energy by element
ElementTypeMapArray<Real> thermal_energy;
/// Solver
Solver * solver;
/// analysis method
AnalysisMethod method;
/// pointer to the pbc synchronizer
PBCSynchronizer * pbc_synch;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "heat_transfer_model_inline_impl.cc"
#endif
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const HeatTransferModel & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_HEAT_TRANSFER_MODEL_HH__ */
diff --git a/src/model/heat_transfer/heat_transfer_model_inline_impl.cc b/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
index 00007b56a..bdf636e3a 100644
--- a/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
+++ b/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
@@ -1,467 +1,468 @@
/**
* @file heat_transfer_model_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
*
- * @date creation: Sun May 01 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Aug 20 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Implementation of the inline functions of the HeatTransferModel class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline FEEngine & HeatTransferModel::getFEEngineBoundary(const std::string & name) {
return dynamic_cast<FEEngine &>(getFEEngineClassBoundary<MyFEEngineType>(name));
}
/* -------------------------------------------------------------------------- */
inline UInt HeatTransferModel::getNbDataToPack(SynchronizationTag tag) const{
AKANTU_DEBUG_IN();
UInt size = 0;
UInt nb_nodes = getFEEngine().getMesh().getNbNodes();
switch(tag) {
case _gst_htm_temperature:
case _gst_htm_capacity: {
size += nb_nodes * sizeof(Real);
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline UInt HeatTransferModel::getNbDataToUnpack(SynchronizationTag tag) const{
AKANTU_DEBUG_IN();
UInt size = 0;
UInt nb_nodes = getFEEngine().getMesh().getNbNodes();
switch(tag) {
case _gst_htm_capacity:
case _gst_htm_temperature: {
size += nb_nodes * sizeof(Real);
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void HeatTransferModel::packData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag) const{
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_htm_capacity:
buffer << (*capacity_lumped)(index);
break;
case _gst_htm_temperature: {
buffer << (*temperature)(index);
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void HeatTransferModel::unpackData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_htm_capacity: {
buffer >> (*capacity_lumped)(index);
break;
}
case _gst_htm_temperature: {
buffer >> (*temperature)(index);
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline UInt HeatTransferModel::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
UInt nb_nodes_per_element = 0;
Array<Element>::const_iterator<Element> it = elements.begin();
Array<Element>::const_iterator<Element> end = elements.end();
for (; it != end; ++it) {
const Element & el = *it;
nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
}
#ifndef AKANTU_NDEBUG
size += elements.getSize() * spatial_dimension * sizeof(Real); /// position of the barycenter of the element (only for check)
// size += spatial_dimension * nb_nodes_per_element * sizeof(Real); /// position of the nodes of the element
#endif
switch(tag) {
case _gst_htm_capacity: {
size += nb_nodes_per_element * sizeof(Real); // capacity vector
break;
}
case _gst_htm_temperature: {
size += nb_nodes_per_element * sizeof(Real); // temperature
break;
}
case _gst_htm_gradient_temperature: {
size += getNbIntegrationPoints(elements) * spatial_dimension * sizeof(Real); // temperature gradient
size += nb_nodes_per_element * sizeof(Real); // nodal temperatures
// size += spatial_dimension * nb_nodes_per_element * sizeof(Real); // shape derivatives
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void HeatTransferModel::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
#ifndef AKANTU_NDEBUG
Array<Element>::const_iterator<Element> bit = elements.begin();
Array<Element>::const_iterator<Element> bend = elements.end();
for (; bit != bend; ++bit) {
const Element & element = *bit;
Vector<Real> barycenter(spatial_dimension);
mesh.getBarycenter(element.element, element.type, barycenter.storage(), element.ghost_type);
buffer << barycenter;
}
// packNodalDataHelper(mesh.getNodes(), buffer, elements);
#endif
switch (tag){
case _gst_htm_capacity: {
packNodalDataHelper(*capacity_lumped, buffer, elements, mesh);
break;
}
case _gst_htm_temperature: {
packNodalDataHelper(*temperature, buffer, elements, mesh);
break;
}
case _gst_htm_gradient_temperature: {
packElementalDataHelper(temperature_gradient, buffer, elements, true, getFEEngine());
packNodalDataHelper(*temperature, buffer, elements, mesh);
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
}
/* -------------------------------------------------------------------------- */
inline void HeatTransferModel::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
#ifndef AKANTU_NDEBUG
Array<Element>::const_iterator<Element> bit = elements.begin();
Array<Element>::const_iterator<Element> bend = elements.end();
for (; bit != bend; ++bit) {
const Element & element = *bit;
Vector<Real> barycenter_loc(spatial_dimension);
mesh.getBarycenter(element.element, element.type, barycenter_loc.storage(), element.ghost_type);
Vector<Real> barycenter(spatial_dimension);
buffer >> barycenter;
Real tolerance = 1e-15;
for (UInt i = 0; i < spatial_dimension; ++i) {
if(!(std::abs(barycenter(i) - barycenter_loc(i)) <= tolerance))
AKANTU_DEBUG_ERROR("Unpacking an unknown value for the element: "
<< element
<< "(barycenter[" << i << "] = " << barycenter_loc(i)
<< " and buffer[" << i << "] = " << barycenter(i) << ") - tag: " << tag);
}
}
// Vector<Real> coords(spatial_dimension);
// Real * nodes = getFEEngine().getMesh().getNodes().storage();
// for (UInt n = 0; n < nb_nodes_per_element; ++n) {
// buffer >> coords;
// UInt offset_conn = conn[el_offset + n];
// Real * coords_local = nodes+spatial_dimension*offset_conn;
// for (UInt i = 0; i < spatial_dimension; ++i) {
// if(!(std::abs(coords(i) - coords_local[i]) <= tolerance))
// AKANTU_EXCEPTION("Unpacking to wrong node for the element : "
// << element
// << "(coords[" << i << "] = " << coords_local[i]
// << " and buffer[" << i << "] = " << coords(i) << ")");
// }
// }
#endif
switch (tag){
case _gst_htm_capacity: {
unpackNodalDataHelper(*capacity_lumped, buffer, elements, mesh);
break;
}
case _gst_htm_temperature: {
unpackNodalDataHelper(*temperature, buffer, elements, mesh);
break;
}
case _gst_htm_gradient_temperature: {
unpackElementalDataHelper(temperature_gradient, buffer, elements, true, getFEEngine());
unpackNodalDataHelper(*temperature, buffer, elements, mesh);
// // Real tolerance = 1e-15;
// if (!Math::are_vector_equal(spatial_dimension,gtemp.storage(),it_gtemp[element.element].storage())){
// Real dist = Math::distance_3d(gtemp.storage(), it_gtemp[element.element].storage());
// debug::debugger.getOutputStream().precision(20);
// std::stringstream temperatures_str;
// temperatures_str.precision(20);
// temperatures_str << std::scientific << "temperatures are ";
// for (UInt n = 0; n < nb_nodes_per_element; ++n) {
// UInt offset_conn = conn[el_offset + n];
// temperatures_str << (*temperature)(offset_conn) << " ";
// }
// Array<Real>::matrix_iterator it_shaped =
// const_cast<Array<Real> &>(getFEEngine().getShapesDerivatives(element.type, ghost_type))
// .begin(nb_nodes_per_element,spatial_dimension);
// AKANTU_EXCEPTION("packed gradient do not match for element " << element.element << std::endl
// << "buffer is " << gtemp << " local is " << it_gtemp[element.element]
// << " dist is " << dist << std::endl
// << temperatures_str.str() << std::endl
// << std::scientific << std::setprecision(20)
// << " distant temperatures " << temp_nodes
// << "temperature gradient size " << temperature_gradient(element.type, ghost_type).getSize()
// << " number of ghost elements " << getFEEngine().getMesh().getNbElement(element.type,_ghost)
// << std::scientific << std::setprecision(20)
// << " shaped " << shaped
// << std::scientific << std::setprecision(20)
// << " local shaped " << it_shaped[element.element]);
// }
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
}
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool HeatTransferModel::solveStep(Real tolerance,
UInt max_iteration) {
Real error = 0.;
return this->template solveStep<cmethod,criteria>(tolerance,
error,
max_iteration);
}
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool HeatTransferModel::solveStep(Real tolerance, Real & error,
UInt max_iteration,
bool do_not_factorize) {
//EventManager::sendEvent(HeatTransferModelEvent::BeforeSolveStepEvent(method));
this->implicitPred();
this->updateResidual();
AKANTU_DEBUG_ASSERT(conductivity_matrix != NULL,
"You should first initialize the implicit solver and assemble the conductivity matrix");
bool need_factorize = !do_not_factorize;
if (method == _implicit_dynamic) {
AKANTU_DEBUG_ASSERT(capacity_matrix != NULL,
"You should first initialize the implicit solver and assemble the mass matrix");
}
switch (cmethod) {
case _scm_newton_raphson_tangent:
case _scm_newton_raphson_tangent_not_computed:
break;
case _scm_newton_raphson_tangent_modified:
this->assembleConductivityMatrix();
break;
default:
AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
}
this->n_iter = 0;
bool converged = false;
error = 0.;
if(criteria == _scc_residual) {
converged = this->testConvergence<criteria> (tolerance, error);
if(converged) return converged;
}
do {
if (cmethod == _scm_newton_raphson_tangent)
this->assembleConductivityMatrix();
solve<GeneralizedTrapezoidal::_temperature_corrector>(*increment, 1., need_factorize);
this->implicitCorr();
if(criteria == _scc_residual) this->updateResidual();
converged = this->testConvergence<criteria> (tolerance, error);
if(criteria == _scc_increment && !converged) this->updateResidual();
// this->dump();
this->n_iter++;
AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration "
<< std::setw(std::log10(max_iteration)) << this->n_iter
<< ": error " << error << (converged ? " < " : " > ") << tolerance);
switch (cmethod) {
case _scm_newton_raphson_tangent:
need_factorize = true;
break;
case _scm_newton_raphson_tangent_not_computed:
case _scm_newton_raphson_tangent_modified:
need_factorize = false;
break;
default:
AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
}
} while (!converged && this->n_iter < max_iteration);
// this makes sure that you have correct strains and stresses after the solveStep function (e.g., for dumping)
if(criteria == _scc_increment) this->updateResidual();
if (converged) {
//EventManager::sendEvent(HeatTransferModelEvent::AfterSolveStepEvent(method));
} else if(this->n_iter == max_iteration) {
AKANTU_DEBUG_WARNING("[" << criteria << "] Convergence not reached after "
<< std::setw(std::log10(max_iteration)) << this->n_iter <<
" iteration" << (this->n_iter == 1 ? "" : "s") << "!" << std::endl);
}
return converged;
}
/* -------------------------------------------------------------------------- */
template <GeneralizedTrapezoidal::IntegrationSchemeCorrectorType type>
void HeatTransferModel::solve(Array<Real> &increment, Real block_val,
bool need_factorize, bool has_profile_changed){
updateResidualInternal(); //doesn't do anything for static
if(need_factorize) {
Real c = 0.,e = 0.;
if(method == _static) {
AKANTU_DEBUG_INFO("Solving K inc = r");
e = 1.;
} else {
AKANTU_DEBUG_INFO("Solving (c M + e K) inc = r");
GeneralizedTrapezoidal * trap_int = dynamic_cast<GeneralizedTrapezoidal*>(integrator);
c = trap_int->getTemperatureRateCoefficient<type>(time_step);
e = trap_int->getTemperatureCoefficient<type>(time_step);
// std::cout << "c " << c << " e " << e << std::endl;
}
jacobian_matrix->clear();
// J = c M + e K
if(conductivity_matrix)
jacobian_matrix->add(*conductivity_matrix, e);
if(capacity_matrix)
jacobian_matrix->add(*capacity_matrix, c);
#if !defined(AKANTU_NDEBUG)
// if(capacity_matrix && AKANTU_DEBUG_TEST(dblDump))
capacity_matrix->saveMatrix("M.mtx");
#endif
jacobian_matrix->applyBoundary(*blocked_dofs, block_val);
#if !defined(AKANTU_NDEBUG)
//if(AKANTU_DEBUG_TEST(dblDump))
jacobian_matrix->saveMatrix("J.mtx");
#endif
solver->factorize();
}
// if (rhs.getSize() != 0)
// solver->setRHS(rhs);
// else
solver->setOperators();
solver->setRHS(*residual);
// solve @f[ J \delta w = r @f]
solver->solve(increment);
UInt nb_nodes = temperature->getSize();
UInt nb_degree_of_freedom = temperature->getNbComponent() * nb_nodes;
bool * blocked_dofs_val = blocked_dofs->storage();
Real * increment_val = increment.storage();
for (UInt j = 0; j < nb_degree_of_freedom;
++j,++increment_val, ++blocked_dofs_val) {
if ((*blocked_dofs_val))
*increment_val = 0.0;
}
}
/* -------------------------------------------------------------------------- */
diff --git a/src/model/integration_scheme/generalized_trapezoidal.hh b/src/model/integration_scheme/generalized_trapezoidal.hh
index 43cc7fef6..ea6cd5738 100644
--- a/src/model/integration_scheme/generalized_trapezoidal.hh
+++ b/src/model/integration_scheme/generalized_trapezoidal.hh
@@ -1,169 +1,170 @@
/**
* @file generalized_trapezoidal.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jul 04 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Fri Oct 23 2015
*
* @brief Generalized Trapezoidal Method. This implementation is taken from
* Méthodes numériques en mécanique des solides by Alain Curnier \note{ISBN:
* 2-88074-247-1}
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__
#define __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__
#include "integration_scheme_1st_order.hh"
__BEGIN_AKANTU__
/**
* The two differentiate equation (thermal and kinematic) are :
* @f{eqnarray*}{
* C\dot{u}_{n+1} + Ku_{n+1} = q_{n+1}\\
* u_{n+1} = u_{n} + (1-\alpha) \Delta t \dot{u}_{n} + \alpha \Delta t \dot{u}_{n+1}
* @f}
*
* To solve it :
* Predictor :
* @f{eqnarray*}{
* u^0_{n+1} &=& u_{n} + (1-\alpha) \Delta t v_{n} \\
* \dot{u}^0_{n+1} &=& \dot{u}_{n}
* @f}
*
* Solve :
* @f[ (a C + b K^i_{n+1}) w = q_{n+1} - f^i_{n+1} - C \dot{u}^i_{n+1} @f]
*
* Corrector :
* @f{eqnarray*}{
* \dot{u}^{i+1}_{n+1} &=& \dot{u}^{i}_{n+1} + a w \\
* u^{i+1}_{n+1} &=& u^{i}_{n+1} + b w
* @f}
*
* a and b depends on the resolution method : temperature (u) or temperature rate (@f$\dot{u}@f$)
*
* For temperature : @f$ w = \delta u, a = 1 / (\alpha \Delta t) , b = 1 @f$ @n
* For temperature rate : @f$ w = \delta \dot{u}, a = 1, b = \alpha \Delta t @f$
*/
class GeneralizedTrapezoidal : public IntegrationScheme1stOrder {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
GeneralizedTrapezoidal(Real alpha) : alpha(alpha) {};
virtual ~GeneralizedTrapezoidal() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void integrationSchemePred(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs);
virtual void integrationSchemeCorrTemp(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta);
virtual void integrationSchemeCorrTempRate(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta);
public:
/// the coeffichent @f{b@f} in the description
template<IntegrationSchemeCorrectorType type>
Real getTemperatureCoefficient(Real delta_t);
/// the coeffichent @f{a@f} in the description
template<IntegrationSchemeCorrectorType type>
Real getTemperatureRateCoefficient(Real delta_t);
private:
template<IntegrationSchemeCorrectorType type>
void integrationSchemeCorr(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Alpha, alpha, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// the @f$\alpha@f$ parameter
const Real alpha;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "generalized_trapezoidal_inline_impl.cc"
#endif
/**
* Forward Euler (explicit) -> condition on delta_t
*/
class ForwardEuler : public GeneralizedTrapezoidal {
public:
ForwardEuler() : GeneralizedTrapezoidal(0.) {};
};
/**
* Trapezoidal rule (implicit), midpoint rule or Crank-Nicolson
*/
class TrapezoidalRule1 : public GeneralizedTrapezoidal {
public:
TrapezoidalRule1() : GeneralizedTrapezoidal(.5) {};
};
/**
* Backward Euler (implicit)
*/
class BackwardEuler : public GeneralizedTrapezoidal {
public:
BackwardEuler() : GeneralizedTrapezoidal(1.) {};
};
__END_AKANTU__
#endif /* __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__ */
diff --git a/src/model/integration_scheme/generalized_trapezoidal_inline_impl.cc b/src/model/integration_scheme/generalized_trapezoidal_inline_impl.cc
index 8b8766182..33106363c 100644
--- a/src/model/integration_scheme/generalized_trapezoidal_inline_impl.cc
+++ b/src/model/integration_scheme/generalized_trapezoidal_inline_impl.cc
@@ -1,146 +1,147 @@
/**
* @file generalized_trapezoidal_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jul 04 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Fri Oct 23 2015
*
* @brief implementation of inline functions
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline void GeneralizedTrapezoidal::integrationSchemePred(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs) {
AKANTU_DEBUG_IN();
UInt nb_nodes = u.getSize();
UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
Real * u_val = u.storage();
Real * u_dot_val = u_dot.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
for (UInt d = 0; d < nb_degree_of_freedom; d++) {
if(!(*blocked_dofs_val)) {
*u_val += (1. - alpha) * delta_t * *u_dot_val;
}
u_val++;
u_dot_val++;
blocked_dofs_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void GeneralizedTrapezoidal::integrationSchemeCorrTemp(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) {
AKANTU_DEBUG_IN();
integrationSchemeCorr<GeneralizedTrapezoidal::_temperature_corrector>(delta_t,
u,
u_dot,
blocked_dofs,
delta);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void GeneralizedTrapezoidal::integrationSchemeCorrTempRate(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) {
AKANTU_DEBUG_IN();
integrationSchemeCorr<GeneralizedTrapezoidal::_temperature_rate_corrector>(delta_t,
u,
u_dot,
blocked_dofs,
delta);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
inline Real GeneralizedTrapezoidal::getTemperatureCoefficient<GeneralizedTrapezoidal::_temperature_corrector>(__attribute__ ((unused)) Real delta_t) {
return 1.;
}
template<>
inline Real GeneralizedTrapezoidal::getTemperatureRateCoefficient<GeneralizedTrapezoidal::_temperature_corrector>(Real delta_t) {
return 1./(alpha * delta_t);
}
/* -------------------------------------------------------------------------- */
template<>
inline Real GeneralizedTrapezoidal::getTemperatureCoefficient<GeneralizedTrapezoidal::_temperature_rate_corrector>(Real delta_t) {
return alpha * delta_t;
}
template<>
inline Real GeneralizedTrapezoidal::getTemperatureRateCoefficient<GeneralizedTrapezoidal::_temperature_rate_corrector>(__attribute__ ((unused)) Real delta_t) {
return 1.;
}
/* -------------------------------------------------------------------------- */
template<GeneralizedTrapezoidal::IntegrationSchemeCorrectorType type>
inline void GeneralizedTrapezoidal::integrationSchemeCorr(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) {
AKANTU_DEBUG_IN();
UInt nb_nodes = u.getSize();
UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
Real e = getTemperatureCoefficient<type>(delta_t);
Real d = getTemperatureRateCoefficient<type>(delta_t);
Real * u_val = u.storage();
Real * u_dot_val = u_dot.storage();
Real * delta_val = delta.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
for (UInt dof = 0; dof < nb_degree_of_freedom; dof++) {
if(!(*blocked_dofs_val)) {
*u_val += e * *delta_val;
*u_dot_val += d * *delta_val;
}
u_val++;
u_dot_val++;
delta_val++;
blocked_dofs_val++;
}
AKANTU_DEBUG_OUT();
}
diff --git a/src/model/integration_scheme/integration_scheme_1st_order.hh b/src/model/integration_scheme/integration_scheme_1st_order.hh
index 9e4c0156d..9a462dc00 100644
--- a/src/model/integration_scheme/integration_scheme_1st_order.hh
+++ b/src/model/integration_scheme/integration_scheme_1st_order.hh
@@ -1,92 +1,93 @@
/**
* @file integration_scheme_1st_order.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Jul 04 2011
- * @date last modification: Wed Mar 13 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Oct 23 2015
*
* @brief Interface of the time integrator of first order
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#ifndef __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__
#define __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__
__BEGIN_AKANTU__
class IntegrationScheme1stOrder {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
enum IntegrationSchemeCorrectorType {
_temperature_corrector,
_temperature_rate_corrector
};
virtual ~IntegrationScheme1stOrder() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void integrationSchemePred(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & boundary) = 0;
virtual void integrationSchemeCorrTemp(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & boundary,
Array<Real> & delta) = 0;
virtual void integrationSchemeCorrTempRate(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & boundary,
Array<Real> & delta) = 0;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
__END_AKANTU__
#include "generalized_trapezoidal.hh"
#endif /* __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__ */
diff --git a/src/model/integration_scheme/integration_scheme_2nd_order.hh b/src/model/integration_scheme/integration_scheme_2nd_order.hh
index 5db2f59cf..8fd8d91c6 100644
--- a/src/model/integration_scheme/integration_scheme_2nd_order.hh
+++ b/src/model/integration_scheme/integration_scheme_2nd_order.hh
@@ -1,99 +1,100 @@
/**
* @file integration_scheme_2nd_order.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Aug 04 2010
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Oct 23 2015
*
* @brief Interface of the integrator of second order
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTEGRATION_SCHEME_2ND_ORDER_HH__
#define __AKANTU_INTEGRATION_SCHEME_2ND_ORDER_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class IntegrationScheme2ndOrder {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
enum IntegrationSchemeCorrectorType {
_acceleration_corrector,
_velocity_corrector,
_displacement_corrector
};
virtual ~IntegrationScheme2ndOrder() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void integrationSchemePred(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs) const = 0;
virtual void integrationSchemeCorrDispl(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) const = 0;
virtual void integrationSchemeCorrAccel(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) const = 0;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
__END_AKANTU__
#include "newmark-beta.hh"
#endif /* __AKANTU_INTEGRATION_SCHEME_2ND_ORDER_HH__ */
diff --git a/src/model/integration_scheme/newmark-beta.hh b/src/model/integration_scheme/newmark-beta.hh
index 43f29b470..70a924505 100644
--- a/src/model/integration_scheme/newmark-beta.hh
+++ b/src/model/integration_scheme/newmark-beta.hh
@@ -1,188 +1,189 @@
/**
* @file newmark-beta.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Oct 05 2010
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Fri Oct 23 2015
*
* @brief implementation of the newmark-@f$\beta@f$ integration scheme. This
* implementation is taken from Méthodes numériques en mécanique des solides by
* Alain Curnier \note{ISBN: 2-88074-247-1}
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NEWMARK_BETA_HH__
#define __AKANTU_NEWMARK_BETA_HH__
/* -------------------------------------------------------------------------- */
#include "integration_scheme_2nd_order.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
* The three differentiate equations (dynamic and cinematic) are :
* @f{eqnarray*}{
* M \ddot{u}_{n+1} + C \dot{u}_{n+1} + K u_{n+1} &=& q_{n+1} \\
* u_{n+1} &=& u_{n} + (1 - \alpha) \Delta t \dot{u}_{n} + \alpha \Delta t \dot{u}_{n+1} + (1/2 - \alpha) \Delta t^2 \ddot{u}_n \\
* \dot{u}_{n+1} &=& \dot{u}_{n} + (1 - \beta) \Delta t \ddot{u}_{n} + \beta \Delta t \ddot{u}_{n+1}
* @f}
*
* Predictor:
* @f{eqnarray*}{
* u^{0}_{n+1} &=& u_{n} + \Delta t \dot{u}_n + \frac{\Delta t^2}{2} \ddot{u}_n \\
* \dot{u}^{0}_{n+1} &=& \dot{u}_{n} + \Delta t \ddot{u}_{n} \\
* \ddot{u}^{0}_{n+1} &=& \ddot{u}_{n}
* @f}
*
* Solve :
* @f[ (c M + d C + e K^i_{n+1}) w = = q_{n+1} - f^i_{n+1} - C \dot{u}^i_{n+1} - M \ddot{u}^i_{n+1} @f]
*
* Corrector :
* @f{eqnarray*}{
* \ddot{u}^{i+1}_{n+1} &=& \ddot{u}^{i}_{n+1} + c w \\
* \dot{u}^{i+1}_{n+1} &=& \dot{u}^{i}_{n+1} + d w \\
* u^{i+1}_{n+1} &=& u^{i}_{n+1} + e w
* @f}
*
* c, d and e are parameters depending on the method used to solve the equations @n
* For acceleration : @f$ w = \delta \ddot{u}, e = \alpha \beta \Delta t^2, d = \beta \Delta t, c = 1 @f$ @n
* For velocity : @f$ w = \delta \dot{u}, e = 1/\beta \Delta t, d = 1, c = \alpha \Delta t @f$ @n
* For displacement : @f$ w = \delta u, e = 1, d = 1/\alpha \Delta t, c = 1/\alpha \beta \Delta t^2 @f$
*/
class NewmarkBeta : public IntegrationScheme2ndOrder {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NewmarkBeta(Real alpha, Real beta) : beta(beta), alpha(alpha), k(0.), h(0.) {};
~NewmarkBeta(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline void integrationSchemePred(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs) const;
inline void integrationSchemeCorrAccel(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) const;
inline void integrationSchemeCorrVeloc(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) const;
inline void integrationSchemeCorrDispl(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) const;
public:
template<IntegrationSchemeCorrectorType type>
Real getAccelerationCoefficient(Real delta_t) const;
template<IntegrationSchemeCorrectorType type>
Real getVelocityCoefficient(Real delta_t) const;
template<IntegrationSchemeCorrectorType type>
Real getDisplacementCoefficient(Real delta_t) const;
private:
template<IntegrationSchemeCorrectorType type>
void integrationSchemeCorr(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Beta, beta, Real);
AKANTU_GET_MACRO(Alpha, alpha, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the @f$\beta@f$ parameter
const Real beta;
/// the @f$\alpha@f$ parameter
const Real alpha;
const Real k;
const Real h;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "newmark-beta_inline_impl.cc"
#endif
/**
* central difference method (explicit)
* undamped stability condition :
* @f$ \Delta t = \alpha \Delta t_{crit} = \frac{2}{\omega_{max}} \leq \min_{e} \frac{l_e}{c_e}
*
*/
class CentralDifference : public NewmarkBeta {
public:
CentralDifference() : NewmarkBeta(0., .5) {};
};
//#include "integration_scheme/central_difference.hh"
/// undamped trapezoidal rule (implicit)
class TrapezoidalRule2 : public NewmarkBeta {
public:
TrapezoidalRule2() : NewmarkBeta(.5, .5) { };
};
__END_AKANTU__
#endif /* __AKANTU_NEWMARK_BETA_HH__ */
diff --git a/src/model/integration_scheme/newmark-beta_inline_impl.cc b/src/model/integration_scheme/newmark-beta_inline_impl.cc
index a1beab3da..f2cdabf5e 100644
--- a/src/model/integration_scheme/newmark-beta_inline_impl.cc
+++ b/src/model/integration_scheme/newmark-beta_inline_impl.cc
@@ -1,230 +1,231 @@
/**
* @file newmark-beta_inline_impl.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Oct 05 2010
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Fri Oct 23 2015
*
* @brief implementation of the newmark-@f$\beta@f$ integration scheme. This
* implementation is taken from Méthodes numériques en mécanique des solides by
* Alain Curnier \note{ISBN: 2-88074-247-1}
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/*
* @f$ \tilde{u_{n+1}} = u_{n} + \Delta t \dot{u}_n + \frac{\Delta t^2}{2} \ddot{u}_n @f$
* @f$ \tilde{\dot{u}_{n+1}} = \dot{u}_{n} + \Delta t \ddot{u}_{n} @f$
* @f$ \tilde{\ddot{u}_{n}} = \ddot{u}_{n} @f$
*/
inline void NewmarkBeta::integrationSchemePred(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs) const {
AKANTU_DEBUG_IN();
UInt nb_nodes = u.getSize();
UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
Real * u_val = u.storage();
Real * u_dot_val = u_dot.storage();
Real * u_dot_dot_val = u_dot_dot.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
for (UInt d = 0; d < nb_degree_of_freedom; d++) {
if(!(*blocked_dofs_val)) {
Real dt_a_n = delta_t * *u_dot_dot_val;
*u_val += (1 - k*alpha) * delta_t * *u_dot_val + (.5 - h*alpha*beta) * delta_t * dt_a_n;
*u_dot_val = (1 - k) * *u_dot_val + (1 - h*beta) * dt_a_n;
*u_dot_dot_val = (1 - h) * *u_dot_dot_val;
}
u_val++;
u_dot_val++;
u_dot_dot_val++;
blocked_dofs_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/*
* @f$ u_{n+1} = \tilde{u_{n+1}} + \alpha \beta \Delta t^2 \delta \ddot{u}_n @f$
* @f$ \dot{u}_{n+1} = \tilde{\dot{u}_{n+1}} + \beta \Delta t * \delta \ddot{u}_{n+1} @f$
* @f$ \ddot{u}_{n+1} = \tilde{\ddot{u}_{n+1}} + \delta \ddot{u}_{n+1} @f$
*/
inline void NewmarkBeta::integrationSchemeCorrAccel(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta
) const {
AKANTU_DEBUG_IN();
integrationSchemeCorr<_acceleration_corrector>(delta_t,
u,
u_dot,
u_dot_dot,
blocked_dofs,
delta);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/*
* @f$ u_{n+1} = \tilde{u_{n+1}} + \alpha \Delta t \delta \dot{u}_n @f$
* @f$ \dot{u}_{n+1} = \tilde{\dot{u}_{n+1}} + \delta \dot{u}_{n+1} @f$
* @f$ \ddot{u}_{n+1} = \tilde{\ddot{u}_{n+1}} + \frac{1}{\beta \Delta t} \delta \dot{u}_{n+1} @f$
*/
inline void NewmarkBeta::integrationSchemeCorrVeloc(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta
) const {
AKANTU_DEBUG_IN();
integrationSchemeCorr<_velocity_corrector>(delta_t,
u,
u_dot,
u_dot_dot,
blocked_dofs,
delta);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/*
* @f$ u_{n+1} = \tilde{u_{n+1}} + \delta u_n @f$
* @f$ \dot{u}_{n+1} = \tilde{\dot{u}_{n+1}} + \frac{1}{\alpha \Delta t} \delta u_{n+1} @f$
* @f$ \ddot{u}_{n+1} = \tilde{\ddot{u}_{n+1}} + \frac{1}{\alpha \beta \Delta t^2} \delta u_{n+1} @f$
*/
inline void NewmarkBeta::integrationSchemeCorrDispl(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta
) const {
AKANTU_DEBUG_IN();
integrationSchemeCorr<_displacement_corrector>(delta_t,
u,
u_dot,
u_dot_dot,
blocked_dofs,
delta);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
inline Real NewmarkBeta::getAccelerationCoefficient<NewmarkBeta::_acceleration_corrector>(__attribute__((unused)) Real delta_t) const {
return 1.;
}
template<>
inline Real NewmarkBeta::getAccelerationCoefficient<NewmarkBeta::_velocity_corrector>(Real delta_t) const {
return 1. / (beta * delta_t);
}
template<>
inline Real NewmarkBeta::getAccelerationCoefficient<NewmarkBeta::_displacement_corrector>(Real delta_t) const {
return 1. / (alpha * beta * delta_t * delta_t);
}
/* -------------------------------------------------------------------------- */
template<>
inline Real NewmarkBeta::getVelocityCoefficient<NewmarkBeta::_acceleration_corrector>(Real delta_t) const {
return beta * delta_t;
}
template<>
inline Real NewmarkBeta::getVelocityCoefficient<NewmarkBeta::_velocity_corrector>(__attribute__((unused)) Real delta_t) const {
return 1.;
}
template<>
inline Real NewmarkBeta::getVelocityCoefficient<NewmarkBeta::_displacement_corrector>(Real delta_t) const {
return 1. / (alpha * delta_t);
}
/* -------------------------------------------------------------------------- */
template<>
inline Real NewmarkBeta::getDisplacementCoefficient<NewmarkBeta::_acceleration_corrector>(Real delta_t) const {
return alpha * beta * delta_t * delta_t;
}
template<>
inline Real NewmarkBeta::getDisplacementCoefficient<NewmarkBeta::_velocity_corrector>(Real delta_t) const {
return alpha * delta_t;
}
template<>
inline Real NewmarkBeta::getDisplacementCoefficient<NewmarkBeta::_displacement_corrector>(__attribute__((unused)) Real delta_t) const {
return 1.;
}
/* -------------------------------------------------------------------------- */
template<NewmarkBeta::IntegrationSchemeCorrectorType type>
void NewmarkBeta::integrationSchemeCorr(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<Real> & u_dot_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta
) const {
AKANTU_DEBUG_IN();
UInt nb_nodes = u.getSize();
UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
Real c = getAccelerationCoefficient<type>(delta_t);
Real d = getVelocityCoefficient<type>(delta_t);
Real e = getDisplacementCoefficient<type>(delta_t);
Real * u_val = u.storage();
Real * u_dot_val = u_dot.storage();
Real * u_dot_dot_val = u_dot_dot.storage();
Real * delta_val = delta.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
for (UInt dof = 0; dof < nb_degree_of_freedom; dof++) {
if(!(*blocked_dofs_val)) {
*u_val += e * *delta_val;
*u_dot_val += d * *delta_val;
*u_dot_dot_val += c * *delta_val;
}
u_val++;
u_dot_val++;
u_dot_dot_val++;
delta_val++;
blocked_dofs_val++;
}
AKANTU_DEBUG_OUT();
}
diff --git a/src/model/model.cc b/src/model/model.cc
index 764277053..ac83e351f 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -1,396 +1,397 @@
/**
* @file model.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Oct 03 2011
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Thu Nov 19 2015
*
* @brief implementation of model common parts
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "model.hh"
#include "element_group.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
Model::Model(Mesh& m, UInt dim, const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id), mesh(m),
spatial_dimension(dim == _all_dimensions ? m.getSpatialDimension() : dim),
synch_registry(NULL),
dof_synchronizer(NULL),
is_pbc_slave_node(0,1,"is_pbc_slave_node") ,
parser(&getStaticParser()) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Model::~Model() {
AKANTU_DEBUG_IN();
FEEngineMap::iterator it;
for (it = fems.begin(); it != fems.end(); ++it) {
if(it->second) delete it->second;
}
for (it = fems_boundary.begin(); it != fems_boundary.end(); ++it) {
if(it->second) delete it->second;
}
delete synch_registry;
delete dof_synchronizer;
dof_synchronizer = NULL;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Model::setParser(Parser & parser){
this->parser = &parser;
}
/* -------------------------------------------------------------------------- */
void Model::initFull(const ModelOptions & options) {
AKANTU_DEBUG_IN();
initModel();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Model::createSynchronizerRegistry(DataAccessor * data_accessor){
synch_registry = new SynchronizerRegistry(*data_accessor);
}
/* -------------------------------------------------------------------------- */
void Model::setPBC(UInt x, UInt y, UInt z){
mesh.computeBoundingBox();
if (x) MeshUtils::computePBCMap(this->mesh, 0, this->pbc_pair);
if (y) MeshUtils::computePBCMap(this->mesh, 1, this->pbc_pair);
if (z) MeshUtils::computePBCMap(this->mesh, 2, this->pbc_pair);
}
/* -------------------------------------------------------------------------- */
void Model::setPBC(SurfacePairList & surface_pairs){
SurfacePairList::iterator s_it;
for(s_it = surface_pairs.begin(); s_it != surface_pairs.end(); ++s_it) {
MeshUtils::computePBCMap(this->mesh, *s_it, this->pbc_pair);
}
}
/* -------------------------------------------------------------------------- */
void Model::initPBC() {
std::map<UInt,UInt>::iterator it = pbc_pair.begin();
std::map<UInt,UInt>::iterator end = pbc_pair.end();
is_pbc_slave_node.resize(mesh.getNbNodes());
#ifndef AKANTU_NDEBUG
Array<Real>::const_vector_iterator coord_it =
mesh.getNodes().begin(this->spatial_dimension);
#endif
while(it != end){
UInt i1 = (*it).first;
is_pbc_slave_node(i1) = true;
#ifndef AKANTU_NDEBUG
UInt i2 = (*it).second;
UInt slave = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i1) : i1;
UInt master = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i2) : i2;
AKANTU_DEBUG_INFO("pairing " << slave << " ("
<< Vector<Real>(coord_it[i1]) << ") with "
<< master << " ("
<< Vector<Real>(coord_it[i2]) << ")");
#endif
++it;
}
}
/* -------------------------------------------------------------------------- */
DistributedSynchronizer & Model::createParallelSynch(MeshPartition * partition,
__attribute__((unused)) DataAccessor * data_accessor){
AKANTU_DEBUG_IN();
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
StaticCommunicator & comm =
StaticCommunicator::getStaticCommunicator();
Int prank = comm.whoAmI();
DistributedSynchronizer * synch = NULL;
if(prank == 0)
synch =
DistributedSynchronizer::createDistributedSynchronizerMesh(getFEEngine().getMesh(),
partition);
else
synch =
DistributedSynchronizer::createDistributedSynchronizerMesh(getFEEngine().getMesh(),
NULL);
AKANTU_DEBUG_OUT();
return *synch;
}
/* -------------------------------------------------------------------------- */
void Model::dumpGroup(const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.dump();
}
/* -------------------------------------------------------------------------- */
void Model::dumpGroup(const std::string & group_name,
const std::string & dumper_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.dump(dumper_name);
}
/* -------------------------------------------------------------------------- */
void Model::dumpGroup() {
GroupManager::element_group_iterator bit = mesh.element_group_begin();
GroupManager::element_group_iterator bend = mesh.element_group_end();
for(; bit != bend; ++bit) {
bit->second->dump();
}
}
/* -------------------------------------------------------------------------- */
void Model::setGroupDirectory(const std::string & directory) {
GroupManager::element_group_iterator bit = mesh.element_group_begin();
GroupManager::element_group_iterator bend = mesh.element_group_end();
for (; bit != bend; ++bit) {
bit->second->setDirectory(directory);
}
}
/* -------------------------------------------------------------------------- */
void Model::setGroupDirectory(const std::string & directory,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.setDirectory(directory);
}
/* -------------------------------------------------------------------------- */
void Model::setGroupBaseName(const std::string & basename,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.setBaseName(basename);
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Model::getGroupDumper(const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
return group.getDumper();
}
/* -------------------------------------------------------------------------- */
// DUMPER stuff
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldToDumper(const std::string & field_id,
dumper::Field * field,
DumperIOHelper & dumper) {
#ifdef AKANTU_USE_IOHELPER
dumper.registerField(field_id,field);
#endif
}
/* -------------------------------------------------------------------------- */
void Model::addDumpField(const std::string & field_id) {
this->addDumpFieldToDumper(mesh.getDefaultDumperName(),field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldVector(const std::string & field_id) {
this->addDumpFieldVectorToDumper(mesh.getDefaultDumperName(),field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldTensor(const std::string & field_id) {
this->addDumpFieldTensorToDumper(mesh.getDefaultDumperName(),field_id);
}
/* -------------------------------------------------------------------------- */
void Model::setBaseName(const std::string & field_id) {
mesh.setBaseName(field_id);
}
/* -------------------------------------------------------------------------- */
void Model::setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename) {
mesh.setBaseNameToDumper(dumper_name,basename);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id) {
this->addDumpGroupFieldToDumper(dumper_name,field_id,"all",_ek_regular,false);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupField(const std::string & field_id,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
this->addDumpGroupFieldToDumper(group.getDefaultDumperName(),
field_id,
group_name,_ek_regular,false);
}
/* -------------------------------------------------------------------------- */
void Model::removeDumpGroupField(const std::string & field_id,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
this->removeDumpGroupFieldFromDumper(group.getDefaultDumperName(),
field_id,
group_name);
}
/* -------------------------------------------------------------------------- */
void Model::removeDumpGroupFieldFromDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.removeDumpFieldFromDumper(dumper_name, field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id) {
this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular, 3);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldVector(const std::string & field_id,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
this->addDumpGroupFieldVectorToDumper(group.getDefaultDumperName(),
field_id,
group_name);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name) {
this->addDumpGroupFieldToDumper(dumper_name,field_id,group_name,_ek_regular,true);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldTensorToDumper(const std::string & dumper_name,
const std::string & field_id) {
this->addDumpGroupFieldToDumper(dumper_name,field_id,"all",_ek_regular,true);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag) {
this->addDumpGroupFieldToDumper(dumper_name,
field_id,
group_name,
this->spatial_dimension,
element_kind,
padding_flag);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & element_kind,
bool padding_flag) {
#ifdef AKANTU_USE_IOHELPER
dumper::Field * field = NULL;
if (!field) field = this->createNodalFieldReal(field_id,group_name,padding_flag);
if (!field) field = this->createNodalFieldUInt(field_id,group_name,padding_flag);
if (!field) field = this->createNodalFieldBool(field_id,group_name,padding_flag);
if (!field) field = this->createElementalField(field_id,group_name,padding_flag,spatial_dimension,element_kind);
if (!field) field =
this->mesh.createFieldFromAttachedData<UInt>(field_id,group_name,
element_kind);
if (!field) field =
this->mesh.createFieldFromAttachedData<Real>(field_id,group_name,
element_kind);
if (!field) AKANTU_DEBUG_WARNING("No field could be found based on name: " << field_id);
if (field) {
DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name,group_name);
this->addDumpGroupFieldToDumper(field_id,field,dumper);
}
#endif
}
/* -------------------------------------------------------------------------- */
void Model::dump() {
mesh.dump();
}
/* -------------------------------------------------------------------------- */
void Model::setDirectory(const std::string & directory) {
mesh.setDirectory(directory);
}
/* -------------------------------------------------------------------------- */
void Model::setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory) {
mesh.setDirectoryToDumper(dumper_name,directory);
}
/* -------------------------------------------------------------------------- */
void Model::setTextModeToDumper(){
mesh.setTextModeToDumper();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/model.hh b/src/model/model.hh
index 283a95e6a..a209eaa20 100644
--- a/src/model/model.hh
+++ b/src/model/model.hh
@@ -1,326 +1,327 @@
/**
* @file model.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Jul 27 2010
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Oct 16 2015
*
* @brief Interface of a model
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MODEL_HH__
#define __AKANTU_MODEL_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_memory.hh"
#include "mesh.hh"
#include "fe_engine.hh"
#include "mesh_utils.hh"
#include "synchronizer_registry.hh"
#include "distributed_synchronizer.hh"
#include "static_communicator.hh"
#include "mesh_partition.hh"
#include "dof_synchronizer.hh"
#include "pbc_synchronizer.hh"
#include "parser.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
struct ModelOptions {
virtual ~ModelOptions() {}
};
class DumperIOHelper;
class Model : public Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef Mesh mesh_type;
Model(Mesh& mesh, UInt spatial_dimension = _all_dimensions,
const ID & id = "model",
const MemoryID & memory_id = 0);
virtual ~Model();
typedef std::map<std::string, FEEngine *> FEEngineMap;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void initFull(const ModelOptions & options);
virtual void initModel() = 0;
/// create the synchronizer registry object
void createSynchronizerRegistry(DataAccessor * data_accessor);
/// create a parallel synchronizer and distribute the mesh
DistributedSynchronizer & createParallelSynch(MeshPartition * partition,
DataAccessor * data_accessor);
/// change local equation number so that PBC is assembled properly
void changeLocalEquationNumberForPBC(std::map<UInt,UInt> & pbc_pair,UInt dimension);
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const = 0;
/// initialize the model for PBC
void setPBC(UInt x, UInt y, UInt z);
void setPBC(SurfacePairList & surface_pairs);
virtual void initPBC();
/// set the parser to use
void setParser(Parser & parser);
/* ------------------------------------------------------------------------ */
/* Access to the dumpable interface of the boundaries */
/* ------------------------------------------------------------------------ */
/// Dump the data for a given group
void dumpGroup(const std::string & group_name);
void dumpGroup(const std::string & group_name,
const std::string & dumper_name);
/// Dump the data for all boundaries
void dumpGroup();
/// Set the directory for a given group
void setGroupDirectory(const std::string & directory,
const std::string & group_name);
/// Set the directory for all boundaries
void setGroupDirectory(const std::string & directory);
/// Set the base name for a given group
void setGroupBaseName(const std::string & basename,
const std::string & group_name);
/// Get the internal dumper of a given group
DumperIOHelper & getGroupDumper(const std::string & group_name);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get id of model
AKANTU_GET_MACRO(ID, id, const ID)
/// get the number of surfaces
AKANTU_GET_MACRO(Mesh, mesh, Mesh&);
/// return the object handling equation numbers
AKANTU_GET_MACRO(DOFSynchronizer, *dof_synchronizer, const DOFSynchronizer &)
/// return the object handling synchronizers
AKANTU_GET_MACRO(SynchronizerRegistry, *synch_registry, SynchronizerRegistry &)
/// synchronize the boundary in case of parallel run
virtual void synchronizeBoundaries() {};
/// return the fem object associated with a provided name
inline FEEngine & getFEEngine(const ID & name = "") const;
/// return the fem boundary object associated with a provided name
virtual FEEngine & getFEEngineBoundary(const ID & name = "");
/// register a fem object associated with name
template <typename FEEngineClass> inline void registerFEEngineObject(const std::string & name,
Mesh & mesh,
UInt spatial_dimension);
/// unregister a fem object associated with name
inline void unRegisterFEEngineObject(const std::string & name);
/// return the synchronizer registry
SynchronizerRegistry & getSynchronizerRegistry();
/// return the fem object associated with a provided name
template <typename FEEngineClass>
inline FEEngineClass & getFEEngineClass(std::string name = "") const;
/// return the fem boundary object associated with a provided name
template <typename FEEngineClass>
inline FEEngineClass & getFEEngineClassBoundary(std::string name = "");
/// get the pbc pairs
std::map<UInt,UInt> & getPBCPairs(){return pbc_pair;};
/// returns if node is slave in pbc
inline bool isPBCSlaveNode(const UInt node) const;
/// returns the array of pbc slave nodes (boolean information)
AKANTU_GET_MACRO(IsPBCSlaveNode, is_pbc_slave_node, const Array<bool> &)
/* ------------------------------------------------------------------------ */
/* Pack and unpack helper functions */
/* ------------------------------------------------------------------------ */
public:
inline UInt getNbIntegrationPoints(const Array<Element> & elements,
const ID & fem_id = ID()) const;
/* ------------------------------------------------------------------------ */
/* Dumpable interface (kept for convenience) and dumper relative functions */
/* ------------------------------------------------------------------------ */
void setTextModeToDumper();
virtual void addDumpGroupFieldToDumper(const std::string & field_id,
dumper::Field * field,
DumperIOHelper & dumper);
virtual void addDumpField(const std::string & field_id);
virtual void addDumpFieldVector(const std::string & field_id);
virtual void addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldTensorToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldTensor(const std::string & field_id);
virtual void setBaseName(const std::string & basename);
virtual void setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename);
virtual void addDumpGroupField(const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag);
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & element_kind,
bool padding_flag);
virtual void removeDumpGroupField(const std::string & field_id,
const std::string & group_name);
virtual void removeDumpGroupFieldFromDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldVector(const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name);
virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag){return NULL;}
virtual dumper::Field * createNodalFieldUInt(const std::string & field_name,
const std::string & group_name,
bool padding_flag){return NULL;}
virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag){return NULL;}
virtual dumper::Field * createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const UInt & spatial_dimension,
const ElementKind & kind){return NULL;}
void setDirectory(const std::string & directory);
void setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory);
virtual void dump();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Mesh
Mesh & mesh;
/// Spatial dimension of the problem
UInt spatial_dimension;
/// the main fem object present in all models
FEEngineMap fems;
/// the fem object present in all models for boundaries
FEEngineMap fems_boundary;
/// default fem object
std::string default_fem;
/// synchronizer registry
SynchronizerRegistry * synch_registry;
/// handle the equation number things
DOFSynchronizer * dof_synchronizer;
/// pbc pairs
std::map<UInt,UInt> pbc_pair;
/// flag per node to know is pbc slave
Array<bool> is_pbc_slave_node;
/// parser to the pointer to use
Parser * parser;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "model_inline_impl.cc"
#endif
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const Model & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_MODEL_HH__ */
diff --git a/src/model/model_inline_impl.cc b/src/model/model_inline_impl.cc
index 5ed36cf1d..884324de0 100644
--- a/src/model/model_inline_impl.cc
+++ b/src/model/model_inline_impl.cc
@@ -1,207 +1,209 @@
/**
* @file model_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 25 2010
- * @date last modification: Tue Jul 29 2014
+ * @date last modification: Wed Nov 11 2015
*
* @brief inline implementation of the model class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline SynchronizerRegistry & Model::getSynchronizerRegistry(){
AKANTU_DEBUG_ASSERT(synch_registry,"synchronizer registry not initialized:"
<< " did you call createSynchronizerRegistry ?");
return *synch_registry;
}
/* -------------------------------------------------------------------------- */
template <typename FEEngineClass>
inline FEEngineClass & Model::getFEEngineClassBoundary(std::string name) {
AKANTU_DEBUG_IN();
if (name == "") name = default_fem;
FEEngineMap::const_iterator it_boun = fems_boundary.find(name);
FEEngineClass * tmp_fem_boundary;
if (it_boun == fems_boundary.end()){
AKANTU_DEBUG_INFO("Creating FEEngine boundary " << name);
FEEngineMap::const_iterator it = fems.find(name);
AKANTU_DEBUG_ASSERT(it != fems.end(), "The FEEngine " << name << " is not registered");
UInt spatial_dimension = it->second->getElementDimension();
std::stringstream sstr; sstr << id << ":fem_boundary:" << name;
tmp_fem_boundary = new FEEngineClass(it->second->getMesh(),
spatial_dimension-1,
sstr.str(),
memory_id);
fems_boundary[name] = tmp_fem_boundary;
} else {
tmp_fem_boundary = dynamic_cast<FEEngineClass *>(it_boun->second);
}
AKANTU_DEBUG_OUT();
return *tmp_fem_boundary;
}
/* -------------------------------------------------------------------------- */
template <typename FEEngineClass>
inline FEEngineClass & Model::getFEEngineClass(std::string name) const{
AKANTU_DEBUG_IN();
if (name == "") name = default_fem;
FEEngineMap::const_iterator it = fems.find(name);
AKANTU_DEBUG_ASSERT(it != fems.end(), "The FEEngine " << name << " is not registered");
AKANTU_DEBUG_OUT();
return dynamic_cast<FEEngineClass &>(*(it->second));
}
/* -------------------------------------------------------------------------- */
inline void Model::unRegisterFEEngineObject(const std::string & name){
FEEngineMap::iterator it = fems.find(name);
AKANTU_DEBUG_ASSERT(it != fems.end(), "FEEngine object with name "
<< name << " was not found");
delete((*it).second);
fems.erase(it);
if (!fems.empty())
default_fem = (*fems.begin()).first;
}
/* -------------------------------------------------------------------------- */
template <typename FEEngineClass>
inline void Model::registerFEEngineObject(const std::string & name,
Mesh & mesh,
UInt spatial_dimension){
if (fems.size() == 0) default_fem = name;
#ifndef AKANTU_NDEBUG
FEEngineMap::iterator it = fems.find(name);
AKANTU_DEBUG_ASSERT(it == fems.end(), "FEEngine object with name "
<< name << " was already created");
#endif
std::stringstream sstr; sstr << id << ":fem:" << name;
fems[name] = new FEEngineClass(mesh, spatial_dimension, sstr.str(), memory_id);
// MeshUtils::buildFacets(fems[name]->getMesh());
// std::stringstream sstr2; sstr2 << id << ":fem_boundary:" << name;
// fems_boundary[name] = new FEEngineClass(mesh, spatial_dimension-1, sstr2.str(), memory_id);
}
/* -------------------------------------------------------------------------- */
inline FEEngine & Model::getFEEngine(const ID & name) const{
AKANTU_DEBUG_IN();
ID tmp_name = name;
if (name == "") tmp_name = default_fem;
FEEngineMap::const_iterator it = fems.find(tmp_name);
AKANTU_DEBUG_ASSERT(it != fems.end(),
"The FEEngine " << tmp_name << " is not registered");
AKANTU_DEBUG_OUT();
return *(it->second);
}
/* -------------------------------------------------------------------------- */
inline FEEngine & Model::getFEEngineBoundary(const ID & name){
AKANTU_DEBUG_IN();
ID tmp_name = name;
if (name == "") tmp_name = default_fem;
FEEngineMap::const_iterator it = fems_boundary.find(tmp_name);
AKANTU_DEBUG_ASSERT(it != fems_boundary.end(),
"The FEEngine boundary " << tmp_name << " is not registered");
AKANTU_DEBUG_ASSERT(it->second != NULL,
"The FEEngine boundary " << tmp_name << " was not created");
AKANTU_DEBUG_OUT();
return *(it->second);
}
/* -------------------------------------------------------------------------- */
/// @todo : should merge with a single function which handles local and global
inline void Model::changeLocalEquationNumberForPBC(std::map<UInt,UInt> & pbc_pair,
UInt dimension) {
Array<Int> & local_eq_num = *dof_synchronizer->getLocalDOFEquationNumbersPointer();
Array<Int> & global_eq_num = *dof_synchronizer->getGlobalDOFEquationNumbersPointer();
for (std::map<UInt,UInt>::iterator it = pbc_pair.begin();
it != pbc_pair.end();++it) {
Int node_master = (*it).second;
Int node_slave = (*it).first;
for (UInt i = 0; i < dimension; ++i) {
local_eq_num(node_slave * dimension + i) =
dimension * node_master + i;
if(mesh.isDistributed()) {
global_eq_num(node_slave * dimension+i) =
dimension * mesh.getNodeGlobalId(node_master) + i;
}
else {
global_eq_num(node_slave * dimension+i) =
dimension * node_master + i;
}
}
}
}
/* -------------------------------------------------------------------------- */
inline bool Model::isPBCSlaveNode(const UInt node) const {
// if no pbc is defined, is_pbc_slave_node is of size zero
if (is_pbc_slave_node.getSize() == 0)
return false;
else
return is_pbc_slave_node(node);
}
/* -------------------------------------------------------------------------- */
inline UInt Model::getNbIntegrationPoints(const Array<Element> & elements,
const ID & fem_id) const {
UInt nb_quad = 0;
Array<Element>::const_iterator<Element> it = elements.begin();
Array<Element>::const_iterator<Element> end = elements.end();
for (; it != end; ++it) {
const Element & el = *it;
nb_quad += getFEEngine(fem_id).getNbIntegrationPoints(el.type,
el.ghost_type);
}
return nb_quad;
}
/* -------------------------------------------------------------------------- */
diff --git a/src/model/solid_mechanics/material.cc b/src/model/solid_mechanics/material.cc
index 57b7b421f..578f87c41 100644
--- a/src/model/solid_mechanics/material.cc
+++ b/src/model/solid_mechanics/material.cc
@@ -1,1566 +1,1567 @@
/**
* @file material.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Jul 27 2010
- * @date last modification: Tue Sep 16 2014
+ * @date last modification: Tue Nov 24 2015
*
* @brief Implementation of the common part of the material class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material.hh"
#include "solid_mechanics_model.hh"
#include "sparse_matrix.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
Material::Material(SolidMechanicsModel & model, const ID & id) :
Memory(id, model.getMemoryID()),
Parsable(_st_material, id),
is_init(false),
fem(&(model.getFEEngine())),
finite_deformation(false),
name(""),
model(&model),
spatial_dimension(this->model->getSpatialDimension()),
element_filter("element_filter", id, this->memory_id),
stress("stress", *this),
eigengradu("eigen_grad_u", *this),
gradu("grad_u", *this),
green_strain("green_strain",*this),
piola_kirchhoff_2("piola_kirchhoff_2", *this),
potential_energy("potential_energy", *this),
is_non_local(false),
use_previous_stress(false),
use_previous_gradu(false),
interpolation_inverse_coordinates("interpolation inverse coordinates", *this),
interpolation_points_matrices("interpolation points matrices", *this) {
AKANTU_DEBUG_IN();
/// for each connectivity types allocate the element filer array of the material
model.getMesh().initElementTypeMapArray(element_filter,
1,
spatial_dimension,
false,
_ek_regular);
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Material::Material(SolidMechanicsModel & model,
UInt dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id) :
Memory(id, model.getMemoryID()),
Parsable(_st_material, id),
is_init(false),
fem(&(model.getFEEngine())),
finite_deformation(false),
name(""),
model(&model),
spatial_dimension(dim),
element_filter("element_filter", id, this->memory_id),
stress("stress", *this, dim, fe_engine, this->element_filter),
eigengradu("eigen_grad_u", *this, dim, fe_engine, this->element_filter),
gradu("gradu", *this, dim, fe_engine, this->element_filter),
green_strain("green_strain", *this, dim, fe_engine, this->element_filter),
piola_kirchhoff_2("poila_kirchhoff_2", *this, dim, fe_engine, this->element_filter),
potential_energy("potential_energy", *this, dim, fe_engine, this->element_filter),
is_non_local(false),
use_previous_stress(false),
use_previous_gradu(false),
interpolation_inverse_coordinates("interpolation inverse_coordinates", *this,
dim, fe_engine, this->element_filter),
interpolation_points_matrices("interpolation points matrices", *this,
dim, fe_engine, this->element_filter) {
AKANTU_DEBUG_IN();
mesh.initElementTypeMapArray(element_filter,
1,
spatial_dimension,
false,
_ek_regular);
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Material::~Material() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::initialize() {
registerParam("rho" , rho , Real(0.) , _pat_parsable | _pat_modifiable, "Density");
registerParam("name" , name , std::string(), _pat_parsable | _pat_readable);
registerParam("finite_deformation" , finite_deformation , false , _pat_parsable | _pat_readable, "Is finite deformation");
registerParam("inelastic_deformation", inelastic_deformation, false , _pat_internal, "Is inelastic deformation");
/// allocate gradu stress for local elements
eigengradu.initialize(spatial_dimension * spatial_dimension);
gradu.initialize(spatial_dimension * spatial_dimension);
stress.initialize(spatial_dimension * spatial_dimension);
potential_energy.initialize(1);
this->model->registerEventHandler(*this);
}
/* -------------------------------------------------------------------------- */
void Material::initMaterial() {
AKANTU_DEBUG_IN();
if(finite_deformation) {
this->piola_kirchhoff_2.initialize(spatial_dimension * spatial_dimension);
if(use_previous_stress) this->piola_kirchhoff_2.initializeHistory();
this->green_strain.initialize(spatial_dimension * spatial_dimension);
}
if(use_previous_stress) this->stress.initializeHistory();
if(use_previous_gradu) this->gradu.initializeHistory();
for (std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.begin();
it != internal_vectors_real.end();
++it) it->second->resize();
for (std::map<ID, InternalField<UInt> *>::iterator it = internal_vectors_uint.begin();
it != internal_vectors_uint.end();
++it) it->second->resize();
for (std::map<ID, InternalField<bool> *>::iterator it = internal_vectors_bool.begin();
it != internal_vectors_bool.end();
++it) it->second->resize();
is_init = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::savePreviousState() {
AKANTU_DEBUG_IN();
for (std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.begin();
it != internal_vectors_real.end();
++it) {
if(it->second->hasHistory()) it->second->saveCurrentValues();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the residual by assembling @f$\int_{e} \sigma_e \frac{\partial
* \varphi}{\partial X} dX @f$
*
* @param[in] displacements nodes displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void Material::updateResidual(GhostType ghost_type) {
AKANTU_DEBUG_IN();
computeAllStresses(ghost_type);
assembleResidual(ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::assembleResidual(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model->getSpatialDimension();
if(!finite_deformation){
Array<Real> & residual = const_cast<Array<Real> &>(model->getResidual());
Mesh & mesh = fem->getMesh();
Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if (nb_element) {
const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(*it, ghost_type);
UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(*it, ghost_type);
/// compute @f$\sigma \frac{\partial \varphi}{\partial X}@f$ by @f$\mathbf{B}^t \mathbf{\sigma}_q@f$
Array<Real> * sigma_dphi_dx =
new Array<Real>(nb_element*nb_quadrature_points,
size_of_shapes_derivatives, "sigma_x_dphi_/_dX");
Array<Real> * shapesd_filtered =
new Array<Real>(0, size_of_shapes_derivatives, "filtered shapesd");
FEEngine::filterElementalData(mesh, shapes_derivatives, *shapesd_filtered,
*it, ghost_type, elem_filter);
Array<Real> & stress_vect = this->stress(*it, ghost_type);
Array<Real>::matrix_iterator sigma =
stress_vect.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator B =
shapesd_filtered->begin(spatial_dimension, nb_nodes_per_element);
Array<Real>::matrix_iterator Bt_sigma_it =
sigma_dphi_dx->begin(spatial_dimension, nb_nodes_per_element);
for (UInt q = 0; q < nb_element*nb_quadrature_points; ++q, ++sigma, ++B, ++Bt_sigma_it)
Bt_sigma_it->mul<false,false>(*sigma, *B);
delete shapesd_filtered;
/**
* compute @f$\int \sigma * \frac{\partial \varphi}{\partial X}dX@f$ by @f$ \sum_q \mathbf{B}^t
* \mathbf{\sigma}_q \overline w_q J_q@f$
*/
Array<Real> * int_sigma_dphi_dx = new Array<Real>(nb_element,
nb_nodes_per_element * spatial_dimension,
"int_sigma_x_dphi_/_dX");
fem->integrate(*sigma_dphi_dx, *int_sigma_dphi_dx,
size_of_shapes_derivatives,
*it, ghost_type,
elem_filter);
delete sigma_dphi_dx;
/// assemble
fem->assembleArray(*int_sigma_dphi_dx, residual,
model->getDOFSynchronizer().getLocalDOFEquationNumbers(),
residual.getNbComponent(),
*it, ghost_type, elem_filter, -1);
delete int_sigma_dphi_dx;
}
}
}
else{
switch (spatial_dimension){
case 1:
this->assembleResidual<1>(ghost_type);
break;
case 2:
this->assembleResidual<2>(ghost_type);
break;
case 3:
this->assembleResidual<3>(ghost_type);
break;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the stress from the gradu
*
* @param[in] current_position nodes postition + displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void Material::computeAllStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model->getSpatialDimension();
Mesh::type_iterator it = fem->getMesh().firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = fem->getMesh().lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
if (elem_filter.getSize() == 0) continue;
Array<Real> & gradu_vect = gradu(*it, ghost_type);
/// compute @f$\nabla u@f$
fem->gradientOnIntegrationPoints(model->getDisplacement(), gradu_vect,
spatial_dimension,
*it, ghost_type, elem_filter);
gradu_vect -= eigengradu(*it, ghost_type);
/// compute @f$\mathbf{\sigma}_q@f$ from @f$\nabla u@f$
computeStress(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computeAllCauchyStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(finite_deformation,"The Cauchy stress can only be computed if you are working in finite deformation.");
//resizeInternalArray(stress);
Mesh::type_iterator it = fem->getMesh().firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = fem->getMesh().lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it)
switch (spatial_dimension){
case 1:
this->computeCauchyStress<1>(*it, ghost_type);
break;
case 2:
this->computeCauchyStress<2>(*it, ghost_type);
break;
case 3:
this->computeCauchyStress<3>(*it, ghost_type);
break;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::computeCauchyStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::matrix_iterator gradu_it =
this->gradu(el_type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator gradu_end =
this->gradu(el_type, ghost_type).end(dim, dim);
Array<Real>::matrix_iterator piola_it =
this->piola_kirchhoff_2(el_type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator stress_it =
this->stress(el_type, ghost_type).begin(dim, dim);
Matrix<Real> F_tensor(dim, dim);
for (; gradu_it != gradu_end; ++gradu_it, ++piola_it, ++stress_it) {
Matrix<Real> & grad_u = *gradu_it;
Matrix<Real> & piola = *piola_it;
Matrix<Real> & sigma = *stress_it;
gradUToF<dim > (grad_u, F_tensor);
this->computeCauchyStressOnQuad<dim >(F_tensor, piola, sigma);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::setToSteadyState(GhostType ghost_type) {
AKANTU_DEBUG_IN();
const Array<Real> & displacement = model->getDisplacement();
//resizeInternalArray(gradu);
UInt spatial_dimension = model->getSpatialDimension();
Mesh::type_iterator it = fem->getMesh().firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = fem->getMesh().lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
Array<Real> & gradu_vect = gradu(*it, ghost_type);
/// compute @f$\nabla u@f$
fem->gradientOnIntegrationPoints(displacement, gradu_vect,
spatial_dimension,
*it, ghost_type, elem_filter);
setToSteadyState(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the stiffness matrix by assembling @f$\int_{\omega} B^t \times D
* \times B d\omega @f$
*
* @param[in] current_position nodes postition + displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void Material::assembleStiffnessMatrix(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model->getSpatialDimension();
Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
if(finite_deformation){
switch (spatial_dimension) {
case 1:
{
assembleStiffnessMatrixNL < 1 > (*it, ghost_type);
assembleStiffnessMatrixL2 < 1 > (*it, ghost_type);
break;
}
case 2:
{
assembleStiffnessMatrixNL < 2 > (*it, ghost_type);
assembleStiffnessMatrixL2 < 2 > (*it, ghost_type);
break;
}
case 3:
{
assembleStiffnessMatrixNL < 3 > (*it, ghost_type);
assembleStiffnessMatrixL2 < 3 > (*it, ghost_type);
break;
}
}
} else {
switch(spatial_dimension) {
case 1: { assembleStiffnessMatrix<1>(*it, ghost_type); break; }
case 2: { assembleStiffnessMatrix<2>(*it, ghost_type); break; }
case 3: { assembleStiffnessMatrix<3>(*it, ghost_type); break; }
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::assembleStiffnessMatrix(const ElementType & type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<UInt> & elem_filter = element_filter(type, ghost_type);
if (elem_filter.getSize()) {
SparseMatrix & K = const_cast<SparseMatrix &>(model->getStiffnessMatrix());
const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type,
ghost_type);
Array<Real> & gradu_vect = gradu(type, ghost_type);
UInt nb_element = elem_filter.getSize();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type,
ghost_type);
gradu_vect.resize(nb_quadrature_points * nb_element);
fem->gradientOnIntegrationPoints(model->getDisplacement(),
gradu_vect, dim, type, ghost_type,
elem_filter);
UInt tangent_size = getTangentStiffnessVoigtSize(dim);
Array<Real> * tangent_stiffness_matrix =
new Array<Real>(nb_element*nb_quadrature_points, tangent_size * tangent_size,
"tangent_stiffness_matrix");
tangent_stiffness_matrix->clear();
computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
Array<Real> * shapesd_filtered =
new Array<Real>(0, dim * nb_nodes_per_element, "filtered shapesd");
FEEngine::filterElementalData(fem->getMesh(), shapes_derivatives,
*shapesd_filtered, type, ghost_type, elem_filter);
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_d_b_size = dim * nb_nodes_per_element;
Array<Real> * bt_d_b = new Array<Real>(nb_element * nb_quadrature_points,
bt_d_b_size * bt_d_b_size,
"B^t*D*B");
Matrix<Real> B(tangent_size, dim * nb_nodes_per_element);
Matrix<Real> Bt_D(dim * nb_nodes_per_element, tangent_size);
Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
shapesd_filtered->begin(dim, nb_nodes_per_element);
Array<Real>::matrix_iterator Bt_D_B_it
= bt_d_b->begin(dim*nb_nodes_per_element, dim*nb_nodes_per_element);
Array<Real>::matrix_iterator D_it
= tangent_stiffness_matrix->begin(tangent_size, tangent_size);
Array<Real>::matrix_iterator D_end
= tangent_stiffness_matrix->end (tangent_size, tangent_size);
for(; D_it != D_end; ++D_it, ++Bt_D_B_it, ++shapes_derivatives_filtered_it) {
Matrix<Real> & D = *D_it;
Matrix<Real> & Bt_D_B = *Bt_D_B_it;
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
Bt_D.mul<true, false>(B, D);
Bt_D_B.mul<false, false>(Bt_D, B);
}
delete tangent_stiffness_matrix;
delete shapesd_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e = new Array<Real>(nb_element,
bt_d_b_size * bt_d_b_size,
"K_e");
fem->integrate(*bt_d_b, *K_e,
bt_d_b_size * bt_d_b_size,
type, ghost_type,
elem_filter);
delete bt_d_b;
fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type,
elem_filter);
delete K_e;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::assembleStiffnessMatrixNL(const ElementType & type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
SparseMatrix & K = const_cast<SparseMatrix &> (model->getStiffnessMatrix());
const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
//Array<Real> & gradu_vect = delta_gradu(type, ghost_type);
UInt nb_element = elem_filter.getSize();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type, ghost_type);
//gradu_vect.resize(nb_quadrature_points * nb_element);
// fem->gradientOnIntegrationPoints(model->getIncrement(), gradu_vect,
// dim, type, ghost_type, &elem_filter);
Array<Real> * shapes_derivatives_filtered = new Array<Real > (nb_element * nb_quadrature_points,
dim * nb_nodes_per_element,
"shapes derivatives filtered");
Array<Real>::const_matrix_iterator shapes_derivatives_it = shapes_derivatives.begin(spatial_dimension,
nb_nodes_per_element);
Array<Real>::matrix_iterator shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension,
nb_nodes_per_element);
UInt * elem_filter_val = elem_filter.storage();
for (UInt e = 0; e < nb_element; ++e, ++elem_filter_val)
for (UInt q = 0; q < nb_quadrature_points; ++q, ++shapes_derivatives_filtered_it)
*shapes_derivatives_filtered_it = shapes_derivatives_it[*elem_filter_val * nb_quadrature_points + q];
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_s_b_size = dim * nb_nodes_per_element;
Array<Real> * bt_s_b = new Array<Real > (nb_element * nb_quadrature_points,
bt_s_b_size * bt_s_b_size,
"B^t*D*B");
UInt piola_matrix_size = getCauchyStressMatrixSize(dim);
Matrix<Real> B(piola_matrix_size, bt_s_b_size);
Matrix<Real> Bt_S(bt_s_b_size, piola_matrix_size);
Matrix<Real> S(piola_matrix_size, piola_matrix_size);
shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension, nb_nodes_per_element);
Array<Real>::matrix_iterator Bt_S_B_it = bt_s_b->begin(bt_s_b_size,
bt_s_b_size);
Array<Real>::matrix_iterator Bt_S_B_end = bt_s_b->end(bt_s_b_size,
bt_s_b_size);
Array<Real>::matrix_iterator piola_it = piola_kirchhoff_2(type, ghost_type).begin(dim, dim);
for (; Bt_S_B_it != Bt_S_B_end; ++Bt_S_B_it, ++shapes_derivatives_filtered_it, ++piola_it) {
Matrix<Real> & Bt_S_B = *Bt_S_B_it;
Matrix<Real> & Piola_kirchhoff_matrix = *piola_it;
setCauchyStressMatrix< dim >(Piola_kirchhoff_matrix, S);
VoigtHelper<dim>::transferBMatrixToBNL(*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
Bt_S.mul < true, false > (B, S);
Bt_S_B.mul < false, false > (Bt_S, B);
}
delete shapes_derivatives_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e = new Array<Real > (nb_element,
bt_s_b_size * bt_s_b_size,
"K_e");
fem->integrate(*bt_s_b, *K_e,
bt_s_b_size * bt_s_b_size,
type, ghost_type,
elem_filter);
delete bt_s_b;
fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, elem_filter);
delete K_e;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::assembleStiffnessMatrixL2(const ElementType & type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
SparseMatrix & K = const_cast<SparseMatrix &> (model->getStiffnessMatrix());
const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
Array<Real> & gradu_vect = gradu(type, ghost_type);
UInt nb_element = elem_filter.getSize();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type, ghost_type);
gradu_vect.resize(nb_quadrature_points * nb_element);
fem->gradientOnIntegrationPoints(model->getDisplacement(), gradu_vect,
dim, type, ghost_type, elem_filter);
UInt tangent_size = getTangentStiffnessVoigtSize(dim);
Array<Real> * tangent_stiffness_matrix =
new Array<Real > (nb_element*nb_quadrature_points, tangent_size * tangent_size,
"tangent_stiffness_matrix");
tangent_stiffness_matrix->clear();
computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
Array<Real> * shapes_derivatives_filtered = new Array<Real > (nb_element * nb_quadrature_points,
dim * nb_nodes_per_element,
"shapes derivatives filtered");
Array<Real>::const_matrix_iterator shapes_derivatives_it = shapes_derivatives.begin(spatial_dimension,
nb_nodes_per_element);
Array<Real>::matrix_iterator shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension,
nb_nodes_per_element);
UInt * elem_filter_val = elem_filter.storage();
for (UInt e = 0; e < nb_element; ++e, ++elem_filter_val)
for (UInt q = 0; q < nb_quadrature_points; ++q, ++shapes_derivatives_filtered_it)
*shapes_derivatives_filtered_it = shapes_derivatives_it[*elem_filter_val * nb_quadrature_points + q];
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_d_b_size = dim * nb_nodes_per_element;
Array<Real> * bt_d_b = new Array<Real > (nb_element * nb_quadrature_points,
bt_d_b_size * bt_d_b_size,
"B^t*D*B");
Matrix<Real> B(tangent_size, dim * nb_nodes_per_element);
Matrix<Real> B2(tangent_size, dim * nb_nodes_per_element);
Matrix<Real> Bt_D(dim * nb_nodes_per_element, tangent_size);
shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension, nb_nodes_per_element);
Array<Real>::matrix_iterator Bt_D_B_it = bt_d_b->begin(dim*nb_nodes_per_element,
dim * nb_nodes_per_element);
Array<Real>::matrix_iterator grad_u_it = gradu_vect.begin(dim, dim);
Array<Real>::matrix_iterator D_it = tangent_stiffness_matrix->begin(tangent_size,
tangent_size);
Array<Real>::matrix_iterator D_end = tangent_stiffness_matrix->end(tangent_size,
tangent_size);
for (; D_it != D_end; ++D_it, ++Bt_D_B_it, ++shapes_derivatives_filtered_it, ++grad_u_it) {
Matrix<Real> & grad_u = *grad_u_it;
Matrix<Real> & D = *D_it;
Matrix<Real> & Bt_D_B = *Bt_D_B_it;
//transferBMatrixToBL1<dim > (*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
VoigtHelper<dim>::transferBMatrixToBL2(*shapes_derivatives_filtered_it, grad_u, B2, nb_nodes_per_element);
B += B2;
Bt_D.mul < true, false > (B, D);
Bt_D_B.mul < false, false > (Bt_D, B);
}
delete tangent_stiffness_matrix;
delete shapes_derivatives_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e = new Array<Real > (nb_element,
bt_d_b_size * bt_d_b_size,
"K_e");
fem->integrate(*bt_d_b, *K_e,
bt_d_b_size * bt_d_b_size,
type, ghost_type,
elem_filter);
delete bt_d_b;
fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, elem_filter);
delete K_e;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::assembleResidual(GhostType ghost_type){
AKANTU_DEBUG_IN();
Array<Real> & residual = const_cast<Array<Real> &> (model->getResidual());
Mesh & mesh = fem->getMesh();
Mesh::type_iterator it = element_filter.firstType(dim, ghost_type);
Mesh::type_iterator last_type = element_filter.lastType(dim, ghost_type);
for (; it != last_type; ++it) {
const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(*it, ghost_type);
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
if (elem_filter.getSize() == 0) continue;
UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
UInt nb_element = elem_filter.getSize();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(*it, ghost_type);
Array<Real> * shapesd_filtered =
new Array<Real>(0, size_of_shapes_derivatives, "filtered shapesd");
FEEngine::filterElementalData(mesh, shapes_derivatives, *shapesd_filtered,
*it, ghost_type, elem_filter);
Array<Real>::matrix_iterator shapes_derivatives_filtered_it = shapesd_filtered->begin(dim,
nb_nodes_per_element);
//Set stress vectors
UInt stress_size = getTangentStiffnessVoigtSize(dim);
//Set matrices B and BNL*
UInt bt_s_size = dim * nb_nodes_per_element;
Array<Real> * bt_s = new Array<Real > (nb_element * nb_quadrature_points,
bt_s_size,
"B^t*S");
Array<Real>::matrix_iterator grad_u_it = this->gradu(*it, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator grad_u_end = this->gradu(*it, ghost_type).end(dim, dim);
Array<Real>::matrix_iterator stress_it = this->piola_kirchhoff_2(*it, ghost_type).begin(dim, dim);
shapes_derivatives_filtered_it = shapesd_filtered->begin(dim, nb_nodes_per_element);
Array<Real>::matrix_iterator bt_s_it = bt_s->begin(bt_s_size, 1);
Matrix<Real> S_vect(stress_size, 1);
Matrix<Real> B_tensor(stress_size, bt_s_size);
Matrix<Real> B2_tensor(stress_size, bt_s_size);
for (; grad_u_it != grad_u_end; ++grad_u_it, ++stress_it, ++shapes_derivatives_filtered_it, ++bt_s_it) {
Matrix<Real> & grad_u = *grad_u_it;
Matrix<Real> & r_it = *bt_s_it;
Matrix<Real> & S_it = *stress_it;
setCauchyStressArray <dim> (S_it, S_vect);
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B_tensor, nb_nodes_per_element);
VoigtHelper<dim>::transferBMatrixToBL2(*shapes_derivatives_filtered_it, grad_u, B2_tensor, nb_nodes_per_element);
B_tensor += B2_tensor;
r_it.mul < true, false > (B_tensor, S_vect);
}
delete shapesd_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * r_e = new Array<Real > (nb_element,
bt_s_size, "r_e");
fem->integrate(*bt_s, *r_e,
bt_s_size,
*it, ghost_type,
elem_filter);
delete bt_s;
fem->assembleArray(*r_e, residual,
model->getDOFSynchronizer().getLocalDOFEquationNumbers(),
residual.getNbComponent(),
*it, ghost_type, elem_filter, -1);
delete r_e;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computeAllStressesFromTangentModuli(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model->getSpatialDimension();
Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
switch(spatial_dimension) {
case 1: { computeAllStressesFromTangentModuli<1>(*it, ghost_type); break; }
case 2: { computeAllStressesFromTangentModuli<2>(*it, ghost_type); break; }
case 3: { computeAllStressesFromTangentModuli<3>(*it, ghost_type); break; }
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::computeAllStressesFromTangentModuli(const ElementType & type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
Array<Real> & gradu_vect = gradu(type, ghost_type);
UInt nb_element = elem_filter.getSize();
if (nb_element) {
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type, ghost_type);
gradu_vect.resize(nb_quadrature_points * nb_element);
Array<Real> & disp = model->getDisplacement();
fem->gradientOnIntegrationPoints(disp, gradu_vect,
dim, type, ghost_type, elem_filter);
UInt tangent_moduli_size = getTangentStiffnessVoigtSize(dim);
Array<Real> * tangent_moduli_tensors =
new Array<Real>(nb_element*nb_quadrature_points, tangent_moduli_size * tangent_moduli_size,
"tangent_moduli_tensors");
tangent_moduli_tensors->clear();
computeTangentModuli(type, *tangent_moduli_tensors, ghost_type);
Array<Real> * shapesd_filtered =
new Array<Real>(0, dim* nb_nodes_per_element, "filtered shapesd");
FEEngine::filterElementalData(fem->getMesh(), shapes_derivatives, *shapesd_filtered,
type, ghost_type, elem_filter);
Array<Real> filtered_u(nb_element, nb_nodes_per_element * spatial_dimension);
FEEngine::extractNodalToElementField(fem->getMesh(), disp, filtered_u,
type, ghost_type, elem_filter);
/// compute @f$\mathbf{D} \mathbf{B} \mathbf{u}@f$
Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
shapesd_filtered->begin(dim, nb_nodes_per_element);
Array<Real>::matrix_iterator D_it = tangent_moduli_tensors->begin(tangent_moduli_size,
tangent_moduli_size);
Array<Real>::matrix_iterator sigma_it = stress(type, ghost_type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::vector_iterator u_it = filtered_u.begin(spatial_dimension * nb_nodes_per_element);
Matrix<Real> B(tangent_moduli_size, spatial_dimension * nb_nodes_per_element);
Vector<Real> Bu(tangent_moduli_size);
Vector<Real> DBu(tangent_moduli_size);
for (UInt e = 0; e < nb_element; ++e, ++u_it) {
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it, ++shapes_derivatives_filtered_it, ++sigma_it) {
Vector<Real> & u = *u_it;
Matrix<Real> & sigma = *sigma_it;
Matrix<Real> & D = *D_it;
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
Bu.mul<false>(B, u);
DBu.mul<false>(D, Bu);
// Voigt notation to full symmetric tensor
for (UInt i = 0; i < dim; ++i) sigma(i, i) = DBu(i);
if(dim == 2) {
sigma(0,1) = sigma(1,0) = DBu(2);
} else if(dim == 3) {
sigma(1,2) = sigma(2,1) = DBu(3);
sigma(0,2) = sigma(2,0) = DBu(4);
sigma(0,1) = sigma(1,0) = DBu(5);
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computePotentialEnergyByElements() {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = element_filter.firstType(spatial_dimension);
Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension);
for(; it != last_type; ++it) {
computePotentialEnergy(*it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computePotentialEnergy(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real Material::getPotentialEnergy() {
AKANTU_DEBUG_IN();
Real epot = 0.;
computePotentialEnergyByElements();
/// integrate the potential energy for each type of elements
Mesh::type_iterator it = element_filter.firstType(spatial_dimension);
Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension);
for(; it != last_type; ++it) {
epot += fem->integrate(potential_energy(*it, _not_ghost), *it,
_not_ghost, element_filter(*it, _not_ghost));
}
AKANTU_DEBUG_OUT();
return epot;
}
/* -------------------------------------------------------------------------- */
Real Material::getPotentialEnergy(ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
Real epot = 0.;
Vector<Real> epot_on_quad_points(fem->getNbIntegrationPoints(type));
computePotentialEnergyByElement(type, index, epot_on_quad_points);
epot = fem->integrate(epot_on_quad_points, type, element_filter(type)(index));
AKANTU_DEBUG_OUT();
return epot;
}
/* -------------------------------------------------------------------------- */
Real Material::getEnergy(std::string type) {
AKANTU_DEBUG_IN();
if(type == "potential") return getPotentialEnergy();
AKANTU_DEBUG_OUT();
return 0.;
}
/* -------------------------------------------------------------------------- */
Real Material::getEnergy(std::string energy_id, ElementType type, UInt index) {
AKANTU_DEBUG_IN();
if(energy_id == "potential") return getPotentialEnergy(type, index);
AKANTU_DEBUG_OUT();
return 0.;
}
/* -------------------------------------------------------------------------- */
void Material::initElementalFieldInterpolation(const ElementTypeMapArray<Real> & interpolation_points_coordinates) {
AKANTU_DEBUG_IN();
this->fem->initElementalFieldInterpolationFromIntegrationPoints(interpolation_points_coordinates,
this->interpolation_points_matrices,
this->interpolation_inverse_coordinates,
&(this->element_filter));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::interpolateStress(ElementTypeMapArray<Real> & result,
const GhostType ghost_type) {
this->fem->interpolateElementalFieldFromIntegrationPoints(this->stress,
this->interpolation_points_matrices,
this->interpolation_inverse_coordinates,
result,
ghost_type,
&(this->element_filter));
}
/* -------------------------------------------------------------------------- */
void Material::interpolateStressOnFacets(ElementTypeMapArray<Real> & result,
ElementTypeMapArray<Real> & by_elem_result,
const GhostType ghost_type) {
interpolateStress(by_elem_result, ghost_type);
UInt stress_size = this->stress.getNbComponent();
const Mesh & mesh = this->model->getMesh();
const Mesh & mesh_facets = mesh.getMeshFacets();
Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last = this->element_filter.lastType(spatial_dimension, ghost_type);
for (; it != last; ++it) {
ElementType type = *it;
Array<UInt> & elem_fil = element_filter(type, ghost_type);
Array<Real> & by_elem_res = by_elem_result(type, ghost_type);
UInt nb_element = elem_fil.getSize();
UInt nb_element_full = this->model->getMesh().getNbElement(type, ghost_type);
UInt nb_interpolation_points_per_elem = by_elem_res.getSize() / nb_element_full;
const Array<Element> & facet_to_element =
mesh_facets.getSubelementToElement(type, ghost_type);
ElementType type_facet = Mesh::getFacetType(type);
UInt nb_facet_per_elem = facet_to_element.getNbComponent();
UInt nb_quad_per_facet = nb_interpolation_points_per_elem / nb_facet_per_elem;
Element element_for_comparison(type, 0, ghost_type);
const Array< std::vector<Element> > * element_to_facet = NULL;
GhostType current_ghost_type = _casper;
Array<Real> * result_vec = NULL;
Array<Real>::const_matrix_iterator result_it
= by_elem_res.begin_reinterpret(stress_size,
nb_interpolation_points_per_elem,
nb_element_full);
for (UInt el = 0; el < nb_element; ++el){
UInt global_el = elem_fil(el);
element_for_comparison.element = global_el;
for (UInt f = 0; f < nb_facet_per_elem; ++f) {
Element facet_elem = facet_to_element(global_el, f);
UInt global_facet = facet_elem.element;
if (facet_elem.ghost_type != current_ghost_type) {
current_ghost_type = facet_elem.ghost_type;
element_to_facet = &mesh_facets.getElementToSubelement(type_facet,
current_ghost_type);
result_vec = &result(type_facet, current_ghost_type);
}
bool is_second_element = (*element_to_facet)(global_facet)[0] != element_for_comparison;
for (UInt q = 0; q < nb_quad_per_facet; ++q) {
Vector<Real> result_local(result_vec->storage()
+ (global_facet * nb_quad_per_facet + q) * result_vec->getNbComponent()
+ is_second_element * stress_size,
stress_size);
const Matrix<Real> & result_tmp(result_it[global_el]);
result_local = result_tmp(f * nb_quad_per_facet + q);
}
}
}
}
}
/* -------------------------------------------------------------------------- */
template<typename T>
const Array<T> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
return NULL;
}
/* -------------------------------------------------------------------------- */
template<typename T>
Array<T> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
return NULL;
}
/* -------------------------------------------------------------------------- */
template<>
const Array<Real> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) const {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost) ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
return Memory::getArray<Real>(fvect_id);
} catch(debug::Exception & e) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" <<getID() << ") does not contain a vector " << vect_id << "(" << fvect_id << ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
template<>
Array<Real> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost) ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
return Memory::getArray<Real>(fvect_id);
} catch(debug::Exception & e) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() << ") does not contain a vector " << vect_id << "(" << fvect_id << ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
template<>
const Array<UInt> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) const {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost) ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
return Memory::getArray<UInt>(fvect_id);
} catch(debug::Exception & e) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" <<getID() << ") does not contain a vector " << vect_id << "(" << fvect_id << ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
template<>
Array<UInt> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost) ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
return Memory::getArray<UInt>(fvect_id);
} catch(debug::Exception & e) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() << ") does not contain a vector " << vect_id << "(" << fvect_id << ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
template<typename T>
const InternalField<T> & Material::getInternal(const ID & int_id) const {
AKANTU_DEBUG_TO_IMPLEMENT();
return NULL;
}
/* -------------------------------------------------------------------------- */
template<typename T>
InternalField<T> & Material::getInternal(const ID & int_id) {
AKANTU_DEBUG_TO_IMPLEMENT();
return NULL;
}
/* -------------------------------------------------------------------------- */
template<>
const InternalField<Real> & Material::getInternal(const ID & int_id) const {
std::map<ID, InternalField<Real> *>::const_iterator it = internal_vectors_real.find(getID() + ":" + int_id);
if(it == internal_vectors_real.end()) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " (" << (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
template<>
InternalField<Real> & Material::getInternal(const ID & int_id) {
std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.find(getID() + ":" + int_id);
if(it == internal_vectors_real.end()) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " (" << (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
template<>
const InternalField<UInt> & Material::getInternal(const ID & int_id) const {
std::map<ID, InternalField<UInt> *>::const_iterator it = internal_vectors_uint.find(getID() + ":" + int_id);
if(it == internal_vectors_uint.end()) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " (" << (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
template<>
InternalField<UInt> & Material::getInternal(const ID & int_id) {
std::map<ID, InternalField<UInt> *>::iterator it = internal_vectors_uint.find(getID() + ":" + int_id);
if(it == internal_vectors_uint.end()) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " (" << (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
void Material::addElements(const Array<Element> & elements_to_add) {
AKANTU_DEBUG_IN();
UInt mat_id = model->getInternalIndexFromID(getID());
Array<Element>::const_iterator<Element> el_begin = elements_to_add.begin();
Array<Element>::const_iterator<Element> el_end = elements_to_add.end();
for(;el_begin != el_end; ++el_begin) {
const Element & element = *el_begin;
Array<UInt> & mat_indexes = model->getMaterialByElement (element.type, element.ghost_type);
Array<UInt> & mat_loc_num = model->getMaterialLocalNumbering(element.type, element.ghost_type);
UInt index = this->addElement(element.type, element.element, element.ghost_type);
mat_indexes(element.element) = mat_id;
mat_loc_num(element.element) = index;
}
this->resizeInternals();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::removeElements(const Array<Element> & elements_to_remove) {
AKANTU_DEBUG_IN();
Array<Element>::const_iterator<Element> el_begin = elements_to_remove.begin();
Array<Element>::const_iterator<Element> el_end = elements_to_remove.end();
if(el_begin==el_end)
return;
ElementTypeMapArray<UInt> material_local_new_numbering("remove mat filter elem", getID());
Element element;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
element.ghost_type = ghost_type;
ElementTypeMapArray<UInt>::type_iterator it = element_filter.firstType(_all_dimensions, ghost_type, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end = element_filter.lastType(_all_dimensions, ghost_type, _ek_not_defined);
for(; it != end; ++it) {
ElementType type = *it;
element.type = type;
Array<UInt> & elem_filter = this->element_filter(type, ghost_type);
Array<UInt> & mat_loc_num = this->model->getMaterialLocalNumbering(type, ghost_type);
if(!material_local_new_numbering.exists(type, ghost_type))
material_local_new_numbering.alloc(elem_filter.getSize(), 1, type, ghost_type);
Array<UInt> & mat_renumbering = material_local_new_numbering(type, ghost_type);
UInt nb_element = elem_filter.getSize();
element.kind=(*el_begin).kind;
Array<UInt> elem_filter_tmp;
UInt new_id = 0;
for (UInt el = 0; el < nb_element; ++el) {
element.element = elem_filter(el);
if(std::find(el_begin, el_end, element) == el_end) {
elem_filter_tmp.push_back(element.element);
mat_renumbering(el) = new_id;
mat_loc_num(element.element) = new_id;
++new_id;
} else {
mat_renumbering(el) = UInt(-1);
}
}
elem_filter.resize(elem_filter_tmp.getSize());
elem_filter.copy(elem_filter_tmp);
}
}
for (std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.begin();
it != internal_vectors_real.end();
++it) it->second->removeIntegrationPoints(material_local_new_numbering);
for (std::map<ID, InternalField<UInt> *>::iterator it = internal_vectors_uint.begin();
it != internal_vectors_uint.end();
++it) it->second->removeIntegrationPoints(material_local_new_numbering);
for (std::map<ID, InternalField<bool> *>::iterator it = internal_vectors_bool.begin();
it != internal_vectors_bool.end();
++it) it->second->removeIntegrationPoints(material_local_new_numbering);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::resizeInternals() {
AKANTU_DEBUG_IN();
for (std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.begin();
it != internal_vectors_real.end();
++it) it->second->resize();
for (std::map<ID, InternalField<UInt> *>::iterator it = internal_vectors_uint.begin();
it != internal_vectors_uint.end();
++it) it->second->resize();
for (std::map<ID, InternalField<bool> *>::iterator it = internal_vectors_bool.begin();
it != internal_vectors_bool.end();
++it) it->second->resize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::onElementsAdded(__attribute__((unused)) const Array<Element> & element_list,
__attribute__((unused)) const NewElementsEvent & event) {
this->resizeInternals();
}
/* -------------------------------------------------------------------------- */
void Material::onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const RemovedElementsEvent & event) {
UInt my_num = model->getInternalIndexFromID(getID());
ElementTypeMapArray<UInt> material_local_new_numbering("remove mat filter elem", getID());
Array<Element>::const_iterator<Element> el_begin = element_list.begin();
Array<Element>::const_iterator<Element> el_end = element_list.end();
for (ghost_type_t::iterator g = ghost_type_t::begin(); g != ghost_type_t::end(); ++g) {
GhostType gt = *g;
ElementTypeMapArray<UInt>::type_iterator it = new_numbering.firstType(_all_dimensions, gt, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end = new_numbering.lastType (_all_dimensions, gt, _ek_not_defined);
for (; it != end; ++it) {
ElementType type = *it;
if(element_filter.exists(type, gt) && element_filter(type, gt).getSize()){
Array<UInt> & elem_filter = element_filter(type, gt);
Array<UInt> & mat_indexes = this->model->getMaterialByElement (*it, gt);
Array<UInt> & mat_loc_num = this->model->getMaterialLocalNumbering(*it, gt);
UInt nb_element = this->model->getMesh().getNbElement(type, gt);
// all materials will resize of the same size...
mat_indexes.resize(nb_element);
mat_loc_num.resize(nb_element);
if(!material_local_new_numbering.exists(type, gt))
material_local_new_numbering.alloc(elem_filter.getSize(), 1, type, gt);
Array<UInt> & mat_renumbering = material_local_new_numbering(type, gt);
const Array<UInt> & renumbering = new_numbering(type, gt);
Array<UInt> elem_filter_tmp;
UInt ni = 0;
Element el;
el.type = type;
el.ghost_type = gt;
el.kind = Mesh::getKind(type);
for (UInt i = 0; i < elem_filter.getSize(); ++i) {
el.element = elem_filter(i);
if(std::find(el_begin, el_end, el) == el_end) {
UInt new_el = renumbering(el.element);
AKANTU_DEBUG_ASSERT(new_el != UInt(-1), "A not removed element as been badly renumbered");
elem_filter_tmp.push_back(new_el);
mat_renumbering(i) = ni;
mat_indexes(new_el) = my_num;
mat_loc_num(new_el) = ni;
++ni;
} else {
mat_renumbering(i) = UInt(-1);
}
}
elem_filter.resize(elem_filter_tmp.getSize());
elem_filter.copy(elem_filter_tmp);
}
}
}
for (std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.begin();
it != internal_vectors_real.end();
++it) it->second->removeIntegrationPoints(material_local_new_numbering);
for (std::map<ID, InternalField<UInt> *>::iterator it = internal_vectors_uint.begin();
it != internal_vectors_uint.end();
++it) it->second->removeIntegrationPoints(material_local_new_numbering);
for (std::map<ID, InternalField<bool> *>::iterator it = internal_vectors_bool.begin();
it != internal_vectors_bool.end();
++it) it->second->removeIntegrationPoints(material_local_new_numbering);
}
/* -------------------------------------------------------------------------- */
void Material::onBeginningSolveStep(const AnalysisMethod & method) {
this->savePreviousState();
}
/* -------------------------------------------------------------------------- */
void Material::onEndSolveStep(const AnalysisMethod & method) {
ElementTypeMapArray<UInt>::type_iterator it
= this->element_filter.firstType(_all_dimensions, _not_ghost, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end
= element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
for(; it != end; ++it) {
this->updateEnergies(*it, _not_ghost);
}
}
/* -------------------------------------------------------------------------- */
void Material::onDamageIteration() {
this->savePreviousState();
}
/* -------------------------------------------------------------------------- */
void Material::onDamageUpdate() {
ElementTypeMapArray<UInt>::type_iterator it
= this->element_filter.firstType(_all_dimensions, _not_ghost, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end
= element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
for(; it != end; ++it) {
this->updateEnergiesAfterDamage(*it, _not_ghost);
}
}
/* -------------------------------------------------------------------------- */
void Material::onDump(){
if(this->isFiniteDeformation())
this->computeAllCauchyStresses(_not_ghost);
}
/* -------------------------------------------------------------------------- */
void Material::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
std::string type = getID().substr(getID().find_last_of(":") + 1);
stream << space << "Material " << type << " [" << std::endl;
Parsable::printself(stream, indent);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
/// extrapolate internal values
void Material::extrapolateInternal(const ID & id, const Element & element, const Matrix<Real> & point, Matrix<Real> & extrapolated) {
if (this->isInternal<Real>(id, element.kind)) {
UInt nb_element = this->element_filter(element.type, element.ghost_type).getSize();
const ID name = this->getID() + ":" + id;
UInt nb_quads = this->internal_vectors_real[name]->getFEEngine().getNbIntegrationPoints(element.type, element.ghost_type);
const Array<Real> & internal = this->getArray<Real>(id, element.type, element.ghost_type);
UInt nb_component = internal.getNbComponent();
Array<Real>::const_matrix_iterator internal_it = internal.begin_reinterpret(nb_component, nb_quads, nb_element);
Element local_element = this->convertToLocalElement(element);
/// instead of really extrapolating, here the value of the first GP
/// is copied into the result vector. This works only for linear
/// elements
/// @todo extrapolate!!!!
AKANTU_DEBUG_WARNING("This is a fix, values are not truly extrapolated");
const Matrix<Real> & values = internal_it[local_element.element];
UInt index = 0;
Vector<Real> tmp(nb_component);
for (UInt j = 0; j < values.cols(); ++j) {
tmp = values(j);
if (tmp.norm() > 0) {
index = j;
break;
}
}
for (UInt i = 0; i < extrapolated.size(); ++i) {
extrapolated(i) = values(index);
}
}
else {
Matrix<Real> default_values(extrapolated.rows(), extrapolated.cols(), 0.);
extrapolated = default_values;
}
}
/* -------------------------------------------------------------------------- */
void Material::applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const GhostType ghost_type) {
ElementTypeMapArray<UInt>::type_iterator it
= this->element_filter.firstType(_all_dimensions, _not_ghost, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end
= element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
for(; it != end; ++it) {
ElementType type = *it;
if (!element_filter(type, ghost_type).getSize())
continue;
Array<Real>::matrix_iterator eigen_it = this->eigengradu(type, ghost_type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator eigen_end = this->eigengradu(type, ghost_type).end(spatial_dimension,
spatial_dimension);
for(; eigen_it != eigen_end; ++eigen_it) {
Matrix<Real> & current_eigengradu = *eigen_it;
current_eigengradu = prescribed_eigen_grad_u;
}
}
}
__END_AKANTU__
diff --git a/src/model/solid_mechanics/material.hh b/src/model/solid_mechanics/material.hh
index 39f512864..1b4838149 100644
--- a/src/model/solid_mechanics/material.hh
+++ b/src/model/solid_mechanics/material.hh
@@ -1,633 +1,634 @@
/**
* @file material.hh
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Tue Jul 27 2010
- * @date last modification: Tue Sep 16 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Nov 25 2015
*
* @brief Mother class for all materials
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_memory.hh"
#include "aka_voigthelper.hh"
#include "parser.hh"
#include "parsable.hh"
#include "data_accessor.hh"
#include "internal_field.hh"
#include "random_internal_field.hh"
#include "solid_mechanics_model_event_handler.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_HH__
#define __AKANTU_MATERIAL_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class Model;
class SolidMechanicsModel;
}
__BEGIN_AKANTU__
/**
* Interface of all materials
* Prerequisites for a new material
* - inherit from this class
* - implement the following methods:
* \code
* virtual Real getStableTimeStep(Real h, const Element & element = ElementNull);
*
* virtual void computeStress(ElementType el_type,
* GhostType ghost_type = _not_ghost);
*
* virtual void computeTangentStiffness(const ElementType & el_type,
* Array<Real> & tangent_matrix,
* GhostType ghost_type = _not_ghost);
* \endcode
*
*/
class Material : public Memory, public DataAccessor, public Parsable,
public MeshEventHandler,
protected SolidMechanicsModelEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
#if __cplusplus > 199711L
Material(const Material & mat) = delete;
Material & operator=(const Material & mat) = delete;
#endif
/// Initialize material with defaults
Material(SolidMechanicsModel & model, const ID & id = "");
/// Initialize material with custom mesh & fe_engine
Material(SolidMechanicsModel & model,
UInt dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id = "");
/// Destructor
virtual ~Material();
protected:
void initialize();
/* ------------------------------------------------------------------------ */
/* Function that materials can/should reimplement */
/* ------------------------------------------------------------------------ */
protected:
/// constitutive law
virtual void computeStress(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type = _not_ghost) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// compute the tangent stiffness matrix
virtual void computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
__attribute__((unused)) Array<Real> & tangent_matrix,
__attribute__((unused)) GhostType ghost_type = _not_ghost) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// compute the potential energy
virtual void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost);
/// compute the potential energy for an element
virtual void computePotentialEnergyByElement(__attribute__((unused)) ElementType type,
__attribute__((unused)) UInt index,
__attribute__((unused)) Vector<Real> & epot_on_quad_points) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
virtual void updateEnergies(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type = _not_ghost) { }
virtual void updateEnergiesAfterDamage(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type = _not_ghost) {}
/// set the material to steady state (to be implemented for materials that need it)
virtual void setToSteadyState(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type = _not_ghost) { }
/// function called to update the internal parameters when the modifiable
/// parameters are modified
virtual void updateInternalParameters() {}
public:
/// extrapolate internal values
virtual void extrapolateInternal(const ID & id, const Element & element, const Matrix<Real> & points, Matrix<Real> & extrapolated);
/// compute the p-wave speed in the material
virtual Real getPushWaveSpeed(const Element & element) const { AKANTU_DEBUG_TO_IMPLEMENT(); }
/// compute the s-wave speed in the material
virtual Real getShearWaveSpeed(const Element & element) const { AKANTU_DEBUG_TO_IMPLEMENT(); }
/// get a material celerity to compute the stable time step (default: is the push wave speed)
virtual Real getCelerity(const Element & element) const { return getPushWaveSpeed(element); }
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
template<typename T>
void registerInternal(__attribute__((unused)) InternalField<T> & vect) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
template<typename T>
void unregisterInternal(__attribute__((unused)) InternalField<T> & vect) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// initialize the material computed parameter
virtual void initMaterial();
/// compute the residual for this material
virtual void updateResidual(GhostType ghost_type = _not_ghost);
/// assemble the residual for this material
virtual void assembleResidual(GhostType ghost_type);
/// save the stress in the previous_stress if needed
virtual void savePreviousState();
/// compute the stresses for this material
virtual void computeAllStresses(GhostType ghost_type = _not_ghost);
virtual void computeAllStressesFromTangentModuli(GhostType ghost_type = _not_ghost);
virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost);
/// set material to steady state
void setToSteadyState(GhostType ghost_type = _not_ghost);
/// compute the stiffness matrix
virtual void assembleStiffnessMatrix(GhostType ghost_type);
/// add an element to the local mesh filter
inline UInt addElement(const ElementType & type,
UInt element,
const GhostType & ghost_type);
/// add many elements at once
void addElements(const Array<Element> & elements_to_add);
/// remove many element at once
void removeElements(const Array<Element> & elements_to_remove);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/**
* interpolate stress on given positions for each element by means
* of a geometrical interpolation on quadrature points
*/
void interpolateStress(ElementTypeMapArray<Real> & result,
const GhostType ghost_type = _not_ghost);
/**
* interpolate stress on given positions for each element by means
* of a geometrical interpolation on quadrature points and store the
* results per facet
*/
void interpolateStressOnFacets(ElementTypeMapArray<Real> & result,
ElementTypeMapArray<Real> & by_elem_result,
const GhostType ghost_type = _not_ghost);
/**
* function to initialize the elemental field interpolation
* function by inverting the quadrature points' coordinates
*/
void initElementalFieldInterpolation(const ElementTypeMapArray<Real> & interpolation_points_coordinates);
/* ------------------------------------------------------------------------ */
/* Common part */
/* ------------------------------------------------------------------------ */
protected:
/* ------------------------------------------------------------------------ */
inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const;
/// compute the potential energy by element
void computePotentialEnergyByElements();
/// resize the intenals arrays
virtual void resizeInternals();
/* ------------------------------------------------------------------------ */
/* Finite deformation functions */
/* This functions area implementing what is described in the paper of Bathe */
/* et al, in IJNME, Finite Element Formulations For Large Deformation */
/* Dynamic Analysis, Vol 9, 353-386, 1975 */
/* ------------------------------------------------------------------------ */
protected:
/// assemble the residual
template<UInt dim>
void assembleResidual(GhostType ghost_type);
/// Computation of Cauchy stress tensor in the case of finite deformation from
/// the 2nd Piola-Kirchhoff for a given element type
template<UInt dim>
void computeCauchyStress(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type = _not_ghost);
/// Computation the Cauchy stress the 2nd Piola-Kirchhoff and the deformation
/// gradient
template<UInt dim >
inline void computeCauchyStressOnQuad(const Matrix<Real> & F, const Matrix<Real> & S,
Matrix<Real> & cauchy,
const Real & C33 = 1.0) const;
template<UInt dim>
void computeAllStressesFromTangentModuli(const ElementType & type,
GhostType ghost_type);
template<UInt dim>
void assembleStiffnessMatrix(const ElementType & type,
GhostType ghost_type);
/// assembling in finite deformation
template<UInt dim>
void assembleStiffnessMatrixNL(const ElementType & type,
GhostType ghost_type);
template<UInt dim>
void assembleStiffnessMatrixL2(const ElementType & type,
GhostType ghost_type);
/// Size of the Stress matrix for the case of finite deformation see: Bathe et
/// al, IJNME, Vol 9, 353-386, 1975
inline UInt getCauchyStressMatrixSize(UInt spatial_dimension) const;
/// Sets the stress matrix according to Bathe et al, IJNME, Vol 9, 353-386, 1975
template<UInt dim>
inline void setCauchyStressMatrix(const Matrix<Real> & S_t,
Matrix<Real> & sigma);
/// write the stress tensor in the Voigt notation.
template<UInt dim>
inline void setCauchyStressArray(const Matrix<Real> & S_t,
Matrix<Real> & sigma_voight);
/* ------------------------------------------------------------------------ */
/* Conversion functions */
/* ------------------------------------------------------------------------ */
public:
template<UInt dim>
static inline void gradUToF (const Matrix<Real> & grad_u, Matrix<Real> & F);
static inline void rightCauchy(const Matrix<Real> & F, Matrix<Real> & C);
static inline void leftCauchy (const Matrix<Real> & F, Matrix<Real> & B);
template<UInt dim>
static inline void gradUToEpsilon(const Matrix<Real> & grad_u,
Matrix<Real> & epsilon);
template<UInt dim>
static inline void gradUToGreenStrain(const Matrix<Real> & grad_u,
Matrix<Real> & epsilon);
static inline Real stressToVonMises(const Matrix<Real> & stress);
protected:
/// converts global element to local element
inline Element convertToLocalElement(const Element & global_element) const;
/// converts local element to global element
inline Element convertToGlobalElement(const Element & local_element) const;
/// converts global quadrature point to local quadrature point
inline IntegrationPoint convertToLocalPoint(const IntegrationPoint & global_point) const;
/// converts local quadrature point to global quadrature point
inline IntegrationPoint convertToGlobalPoint(const IntegrationPoint & local_point) const;
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
public:
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
template<typename T>
inline void packElementDataHelper(const ElementTypeMapArray<T> & data_to_pack,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const ID & fem_id = ID()) const;
template<typename T>
inline void unpackElementDataHelper(ElementTypeMapArray<T> & data_to_unpack,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const ID & fem_id = ID());
/* ------------------------------------------------------------------------ */
/* MeshEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
virtual void onNodesAdded(
__attribute__((unused)) const Array<UInt> & nodes_list,
__attribute__((unused)) const NewNodesEvent & event) {};
virtual void onNodesRemoved(
__attribute__((unused)) const Array<UInt> & nodes_list,
__attribute__((unused)) const Array<UInt> & new_numbering,
__attribute__((unused)) const RemovedNodesEvent & event) {};
virtual void onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event);
virtual void onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event);
virtual void onElementsChanged(__attribute__((unused)) const Array<Element> & old_elements_list,
__attribute__((unused)) const Array<Element> & new_elements_list,
__attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const ChangedElementsEvent & event) {};
/* ------------------------------------------------------------------------ */
/* SolidMechanicsModelEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
virtual void onBeginningSolveStep(const AnalysisMethod & method);
virtual void onEndSolveStep(const AnalysisMethod & method);
virtual void onDamageIteration();
virtual void onDamageUpdate();
virtual void onDump();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Name, name, const std::string &);
AKANTU_GET_MACRO(Model, *model, const SolidMechanicsModel &)
AKANTU_GET_MACRO(ID, Memory::getID(), const ID &);
AKANTU_GET_MACRO(Rho, rho, Real);
AKANTU_SET_MACRO(Rho, rho, Real);
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// return the potential energy for the subset of elements contained by the material
Real getPotentialEnergy();
/// return the potential energy for the provided element
Real getPotentialEnergy(ElementType & type, UInt index);
/// return the energy (identified by id) for the subset of elements contained by the material
virtual Real getEnergy(std::string energy_id);
/// return the energy (identified by id) for the provided element
virtual Real getEnergy(std::string energy_id, ElementType type, UInt index);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(GradU, gradu, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(PotentialEnergy, potential_energy, Real);
AKANTU_GET_MACRO(GradU, gradu, const ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO(Stress, stress, const ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO(ElementFilter, element_filter, const ElementTypeMapArray<UInt> &);
AKANTU_GET_MACRO(FEEngine, *fem, FEEngine &);
bool isNonLocal() const { return is_non_local; }
template <typename T>
const Array<T> & getArray(const ID & id, const ElementType & type, const GhostType & ghost_type = _not_ghost) const;
template <typename T>
Array<T> & getArray(const ID & id, const ElementType & type, const GhostType & ghost_type = _not_ghost);
template <typename T>
const InternalField<T> & getInternal(const ID & id) const;
template <typename T>
InternalField<T> & getInternal(const ID & id);
template<typename T>
inline bool isInternal(const ID & id, const ElementKind & element_kind) const;
template <typename T>
ElementTypeMap<UInt> getInternalDataPerElem(const ID & id,
const ElementKind & element_kind) const;
bool isFiniteDeformation() const { return finite_deformation; }
bool isInelasticDeformation() const { return inelastic_deformation; }
template <typename T>
inline void setParam(const ID & param, T value);
template <typename T>
inline const T & getParam(const ID & param) const;
template <typename T>
void flattenInternal(const std::string & field_id,
ElementTypeMapArray<T> & internal_flat,
const GhostType ghost_type = _not_ghost,
ElementKind element_kind = _ek_not_defined) const;
/// apply a constant eigengrad_u everywhere in the material
virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const GhostType = _not_ghost);
protected:
bool isInit() const { return is_init; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// boolean to know if the material has been initialized
bool is_init;
std::map<ID, InternalField<Real> *> internal_vectors_real;
std::map<ID, InternalField<UInt> *> internal_vectors_uint;
std::map<ID, InternalField<bool> *> internal_vectors_bool;
protected:
/// Link to the fem object in the model
FEEngine * fem;
/// Finite deformation
bool finite_deformation;
/// Finite deformation
bool inelastic_deformation;
/// material name
std::string name;
/// The model to witch the material belong
SolidMechanicsModel * model;
/// density : rho
Real rho;
/// spatial dimension
UInt spatial_dimension;
/// list of element handled by the material
ElementTypeMapArray<UInt> element_filter;
/// stresses arrays ordered by element types
InternalField<Real> stress;
/// eigengrad_u arrays ordered by element types
InternalField<Real> eigengradu;
/// grad_u arrays ordered by element types
InternalField<Real> gradu;
/// Green Lagrange strain (Finite deformation)
InternalField<Real> green_strain;
/// Second Piola-Kirchhoff stress tensor arrays ordered by element types (Finite deformation)
InternalField<Real> piola_kirchhoff_2;
/// potential energy by element
InternalField<Real> potential_energy;
/// tell if using in non local mode or not
bool is_non_local;
/// tell if the material need the previous stress state
bool use_previous_stress;
/// tell if the material need the previous strain state
bool use_previous_gradu;
/// elemental field interpolation coordinates
InternalField<Real> interpolation_inverse_coordinates;
/// elemental field interpolation points
InternalField<Real> interpolation_points_matrices;
/// vector that contains the names of all the internals that need to
/// be transferred when material interfaces move
std::vector<ID> internals_to_transfer;
};
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const Material & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#include "material_inline_impl.cc"
#include "internal_field_tmpl.hh"
#include "random_internal_field_tmpl.hh"
/* -------------------------------------------------------------------------- */
/* Auto loop */
/* -------------------------------------------------------------------------- */
/// This can be used to automatically write the loop on quadrature points in
/// functions such as computeStress. This macro in addition to write the loop
/// provides two tensors (matrices) sigma and grad_u
#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type) \
Array<Real>::matrix_iterator gradu_it = \
this->gradu(el_type, ghost_type).begin(this->spatial_dimension, \
this->spatial_dimension); \
Array<Real>::matrix_iterator gradu_end = \
this->gradu(el_type, ghost_type).end(this->spatial_dimension, \
this->spatial_dimension); \
\
this->stress(el_type, \
ghost_type).resize(this->gradu(el_type, \
ghost_type).getSize()); \
\
Array<Real>::iterator< Matrix<Real> > stress_it = \
this->stress(el_type, ghost_type).begin(this->spatial_dimension, \
this->spatial_dimension); \
\
if(this->isFiniteDeformation()){ \
this->piola_kirchhoff_2(el_type, \
ghost_type).resize(this->gradu(el_type, \
ghost_type).getSize()); \
stress_it = \
this->piola_kirchhoff_2(el_type, \
ghost_type).begin(this->spatial_dimension, \
this->spatial_dimension); \
} \
\
for(;gradu_it != gradu_end; ++gradu_it, ++stress_it) { \
Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it; \
Matrix<Real> & __attribute__((unused)) sigma = *stress_it
#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END \
} \
/// This can be used to automatically write the loop on quadrature points in
/// functions such as computeTangentModuli. This macro in addition to write the
/// loop provides two tensors (matrices) sigma_tensor, grad_u, and a matrix
/// where the elemental tangent moduli should be stored in Voigt Notation
#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_mat) \
Array<Real>::matrix_iterator gradu_it = \
this->gradu(el_type, ghost_type).begin(this->spatial_dimension, \
this->spatial_dimension); \
Array<Real>::matrix_iterator gradu_end = \
this->gradu(el_type, ghost_type).end(this->spatial_dimension, \
this->spatial_dimension); \
Array<Real>::matrix_iterator sigma_it = \
this->stress(el_type, ghost_type).begin(this->spatial_dimension, \
this->spatial_dimension); \
\
tangent_mat.resize(this->gradu(el_type, ghost_type).getSize()); \
\
UInt tangent_size = \
this->getTangentStiffnessVoigtSize(this->spatial_dimension); \
Array<Real>::matrix_iterator tangent_it = \
tangent_mat.begin(tangent_size, \
tangent_size); \
\
for(;gradu_it != gradu_end; ++gradu_it, ++sigma_it, ++tangent_it) { \
Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it; \
Matrix<Real> & __attribute__((unused)) sigma_tensor = *sigma_it; \
Matrix<Real> & tangent = *tangent_it
#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END \
} \
/* -------------------------------------------------------------------------- */
#define INSTANTIATE_MATERIAL(mat_name) \
template class mat_name<1>; \
template class mat_name<2>; \
template class mat_name<3>
#endif /* __AKANTU_MATERIAL_HH__ */
diff --git a/src/model/solid_mechanics/material_inline_impl.cc b/src/model/solid_mechanics/material_inline_impl.cc
index e9408ba69..319b01603 100644
--- a/src/model/solid_mechanics/material_inline_impl.cc
+++ b/src/model/solid_mechanics/material_inline_impl.cc
@@ -1,461 +1,462 @@
/**
* @file material_inline_impl.cc
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Jul 27 2010
- * @date last modification: Tue Sep 16 2014
+ * @date last modification: Wed Nov 25 2015
*
* @brief Implementation of the inline functions of the class material
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_INLINE_IMPL_CC__
#define __AKANTU_MATERIAL_INLINE_IMPL_CC__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline UInt Material::addElement(const ElementType & type, UInt element,
const GhostType & ghost_type) {
Array<UInt> & el_filter = this->element_filter(type, ghost_type);
el_filter.push_back(element);
return el_filter.getSize() - 1;
}
/* -------------------------------------------------------------------------- */
inline UInt Material::getTangentStiffnessVoigtSize(UInt dim) const {
return (dim * (dim - 1) / 2 + dim);
}
/* -------------------------------------------------------------------------- */
inline UInt Material::getCauchyStressMatrixSize(UInt dim) const {
return (dim * dim);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::gradUToF(const Matrix<Real> & grad_u, Matrix<Real> & F) {
AKANTU_DEBUG_ASSERT(F.size() >= grad_u.size() && grad_u.size() == dim * dim,
"The dimension of the tensor F should be greater or "
"equal to the dimension of the tensor grad_u.");
F.eye();
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
F(i, j) += grad_u(i, j);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::computeCauchyStressOnQuad(const Matrix<Real> & F,
const Matrix<Real> & piola,
Matrix<Real> & sigma,
const Real & C33) const {
Real J = F.det() * sqrt(C33);
Matrix<Real> F_S(dim, dim);
F_S.mul<false, false>(F, piola);
Real constant = J ? 1. / J : 0;
sigma.mul<false, true>(F_S, F, constant);
}
/* -------------------------------------------------------------------------- */
inline void Material::rightCauchy(const Matrix<Real> & F, Matrix<Real> & C) {
C.mul<true, false>(F, F);
}
/* -------------------------------------------------------------------------- */
inline void Material::leftCauchy(const Matrix<Real> & F, Matrix<Real> & B) {
B.mul<false, true>(F, F);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::gradUToEpsilon(const Matrix<Real> & grad_u,
Matrix<Real> & epsilon) {
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
epsilon(i, j) = 0.5 * (grad_u(i, j) + grad_u(j, i));
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::gradUToGreenStrain(const Matrix<Real> & grad_u,
Matrix<Real> & epsilon) {
epsilon.mul<true, false>(grad_u, grad_u, .5);
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
epsilon(i, j) += 0.5 * (grad_u(i, j) + grad_u(j, i));
}
/* -------------------------------------------------------------------------- */
inline Real Material::stressToVonMises(const Matrix<Real> & stress) {
// compute deviatoric stress
UInt dim = stress.cols();
Matrix<Real> deviatoric_stress =
Matrix<Real>::eye(dim, -1. * stress.trace() / 3.);
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
deviatoric_stress(i, j) += stress(i, j);
// return Von Mises stress
return std::sqrt(3. * deviatoric_stress.doubleDot(deviatoric_stress) / 2.);
}
/* ---------------------------------------------------------------------------*/
template <UInt dim>
inline void Material::setCauchyStressArray(const Matrix<Real> & S_t,
Matrix<Real> & sigma_voight) {
AKANTU_DEBUG_IN();
sigma_voight.clear();
// see Finite ekement formulations for large deformation dynamic analysis,
// Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau
/*
* 1d: [ s11 ]'
* 2d: [ s11 s22 s12 ]'
* 3d: [ s11 s22 s33 s23 s13 s12 ]
*/
for (UInt i = 0; i < dim; ++i) // diagonal terms
sigma_voight(i, 0) = S_t(i, i);
for (UInt i = 1; i < dim; ++i) // term s12 in 2D and terms s23 s13 in 3D
sigma_voight(dim + i - 1, 0) = S_t(dim - i - 1, dim - 1);
for (UInt i = 2; i < dim; ++i) // term s13 in 3D
sigma_voight(dim + i, 0) = S_t(0, 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::setCauchyStressMatrix(const Matrix<Real> & S_t,
Matrix<Real> & sigma) {
AKANTU_DEBUG_IN();
sigma.clear();
/// see Finite ekement formulations for large deformation dynamic analysis,
/// Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau
for (UInt i = 0; i < dim; ++i) {
for (UInt m = 0; m < dim; ++m) {
for (UInt n = 0; n < dim; ++n) {
sigma(i * dim + m, i * dim + n) = S_t(m, n);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline Element
Material::convertToLocalElement(const Element & global_element) const {
UInt ge = global_element.element;
#ifndef AKANTU_NDEBUG
UInt model_mat_index = this->model->getMaterialByElement(
global_element.type, global_element.ghost_type)(ge);
UInt mat_index = this->model->getMaterialIndex(this->name);
AKANTU_DEBUG_ASSERT(model_mat_index == mat_index,
"Conversion of a global element in a local element for "
"the wrong material "
<< this->name << std::endl);
#endif
UInt le = this->model->getMaterialLocalNumbering(
global_element.type, global_element.ghost_type)(ge);
Element tmp_quad(global_element.type, le, global_element.ghost_type,
global_element.kind);
return tmp_quad;
}
/* -------------------------------------------------------------------------- */
inline Element
Material::convertToGlobalElement(const Element & local_element) const {
UInt le = local_element.element;
UInt ge =
this->element_filter(local_element.type, local_element.ghost_type)(le);
Element tmp_quad(local_element.type, ge, local_element.ghost_type,
local_element.kind);
return tmp_quad;
}
/* -------------------------------------------------------------------------- */
inline IntegrationPoint
Material::convertToLocalPoint(const IntegrationPoint & global_point) const {
const FEEngine & fem = this->model->getFEEngine();
UInt nb_quad = fem.getNbIntegrationPoints(global_point.type);
Element el =
this->convertToLocalElement(static_cast<const Element &>(global_point));
IntegrationPoint tmp_quad(el, global_point.num_point, nb_quad);
return tmp_quad;
}
/* -------------------------------------------------------------------------- */
inline IntegrationPoint
Material::convertToGlobalPoint(const IntegrationPoint & local_point) const {
const FEEngine & fem = this->model->getFEEngine();
UInt nb_quad = fem.getNbIntegrationPoints(local_point.type);
Element el =
this->convertToGlobalElement(static_cast<const Element &>(local_point));
IntegrationPoint tmp_quad(el, local_point.num_point, nb_quad);
return tmp_quad;
}
/* -------------------------------------------------------------------------- */
inline UInt Material::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
if (tag == _gst_smm_stress) {
return (this->isFiniteDeformation() ? 3 : 1) * spatial_dimension *
spatial_dimension * sizeof(Real) *
this->getModel().getNbIntegrationPoints(elements);
}
return 0;
}
/* -------------------------------------------------------------------------- */
inline void Material::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
if (tag == _gst_smm_stress) {
if (this->isFiniteDeformation()) {
packElementDataHelper(piola_kirchhoff_2, buffer, elements);
packElementDataHelper(gradu, buffer, elements);
}
packElementDataHelper(stress, buffer, elements);
}
}
/* -------------------------------------------------------------------------- */
inline void Material::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
if (tag == _gst_smm_stress) {
if (this->isFiniteDeformation()) {
unpackElementDataHelper(piola_kirchhoff_2, buffer, elements);
unpackElementDataHelper(gradu, buffer, elements);
}
unpackElementDataHelper(stress, buffer, elements);
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline const T & Material::getParam(const ID & param) const {
try {
return get<T>(param);
} catch (...) {
AKANTU_EXCEPTION("No parameter " << param << " in the material "
<< getID());
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void Material::setParam(const ID & param, T value) {
try {
set<T>(param, value);
} catch (...) {
AKANTU_EXCEPTION("No parameter " << param << " in the material "
<< getID());
}
updateInternalParameters();
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void Material::packElementDataHelper(
const ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
const Array<Element> & elements, const ID & fem_id) const {
DataAccessor::packElementalDataHelper<T>(data_to_pack, buffer, elements, true,
model->getFEEngine(fem_id));
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void Material::unpackElementDataHelper(
ElementTypeMapArray<T> & data_to_unpack, CommunicationBuffer & buffer,
const Array<Element> & elements, const ID & fem_id) {
DataAccessor::unpackElementalDataHelper<T>(data_to_unpack, buffer, elements,
true, model->getFEEngine(fem_id));
}
/* -------------------------------------------------------------------------- */
template <>
inline void Material::registerInternal<Real>(InternalField<Real> & vect) {
internal_vectors_real[vect.getID()] = &vect;
}
template <>
inline void Material::registerInternal<UInt>(InternalField<UInt> & vect) {
internal_vectors_uint[vect.getID()] = &vect;
}
template <>
inline void Material::registerInternal<bool>(InternalField<bool> & vect) {
internal_vectors_bool[vect.getID()] = &vect;
}
/* -------------------------------------------------------------------------- */
template <>
inline void Material::unregisterInternal<Real>(InternalField<Real> & vect) {
internal_vectors_real.erase(vect.getID());
}
template <>
inline void Material::unregisterInternal<UInt>(InternalField<UInt> & vect) {
internal_vectors_uint.erase(vect.getID());
}
template <>
inline void Material::unregisterInternal<bool>(InternalField<bool> & vect) {
internal_vectors_bool.erase(vect.getID());
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline bool Material::isInternal(const ID & id,
const ElementKind & element_kind) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
template <>
inline bool Material::isInternal<Real>(const ID & id,
const ElementKind & element_kind) const {
std::map<ID, InternalField<Real> *>::const_iterator internal_array =
internal_vectors_real.find(this->getID() + ":" + id);
if (internal_array == internal_vectors_real.end() ||
internal_array->second->getElementKind() != element_kind)
return false;
return true;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline ElementTypeMap<UInt>
Material::getInternalDataPerElem(const ID & field_id,
const ElementKind & element_kind) const {
if (!this->template isInternal<T>(field_id, element_kind))
AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
<< this->name);
const InternalField<T> & internal_field =
this->template getInternal<T>(field_id);
const FEEngine & fe_engine = internal_field.getFEEngine();
UInt nb_data_per_quad = internal_field.getNbComponent();
ElementTypeMap<UInt> res;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
typedef typename InternalField<T>::type_iterator type_iterator;
type_iterator tit = internal_field.firstType(*gt);
type_iterator tend = internal_field.lastType(*gt);
for (; tit != tend; ++tit) {
UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(*tit, *gt);
res(*tit, *gt) = nb_data_per_quad * nb_quadrature_points;
}
}
return res;
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Material::flattenInternal(const std::string & field_id,
ElementTypeMapArray<T> & internal_flat,
const GhostType ghost_type,
ElementKind element_kind) const {
if (!this->template isInternal<T>(field_id, element_kind))
AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
<< this->name);
const InternalField<T> & internal_field =
this->template getInternal<T>(field_id);
const FEEngine & fe_engine = internal_field.getFEEngine();
const Mesh & mesh = fe_engine.getMesh();
typedef typename InternalField<T>::filter_type_iterator type_iterator;
type_iterator tit = internal_field.filterFirstType(ghost_type);
type_iterator tend = internal_field.filterLastType(ghost_type);
for (; tit != tend; ++tit) {
ElementType type = *tit;
const Array<Real> & src_vect = internal_field(type, ghost_type);
const Array<UInt> & filter = internal_field.getFilter(type, ghost_type);
// total number of elements in the corresponding mesh
UInt nb_element_dst = mesh.getNbElement(type, ghost_type);
// number of element in the internal field
UInt nb_element_src = filter.getSize();
// number of quadrature points per elem
UInt nb_quad_per_elem = fe_engine.getNbIntegrationPoints(type);
// number of data per quadrature point
UInt nb_data_per_quad = internal_field.getNbComponent();
if (!internal_flat.exists(type, ghost_type)) {
internal_flat.alloc(nb_element_dst * nb_quad_per_elem,
nb_data_per_quad, type, ghost_type);
}
if (nb_element_src == 0)
continue;
// number of data per element
UInt nb_data = nb_quad_per_elem * nb_data_per_quad;
Array<Real> & dst_vect = internal_flat(type, ghost_type);
dst_vect.resize(nb_element_dst * nb_quad_per_elem);
Array<UInt>::const_scalar_iterator it = filter.begin();
Array<UInt>::const_scalar_iterator end = filter.end();
Array<Real>::const_vector_iterator it_src =
src_vect.begin_reinterpret(nb_data, nb_element_src);
Array<Real>::vector_iterator it_dst =
dst_vect.begin_reinterpret(nb_data, nb_element_dst);
for (; it != end; ++it, ++it_src) {
it_dst[*it] = *it_src;
}
}
}
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/material_list.hh.in b/src/model/solid_mechanics/material_list.hh.in
index bb5d70ac3..bd556cd36 100644
--- a/src/model/solid_mechanics/material_list.hh.in
+++ b/src/model/solid_mechanics/material_list.hh.in
@@ -1,51 +1,51 @@
/**
- * @file material_list.hh
+ * @file material_list.hh.in
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Oct 29 2013
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sat Jul 18 2015
*
* @brief List of materials and all includes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_LIST_HH__
#define __AKANTU_MATERIAL_LIST_HH__
#include "aka_config.hh"
/* -------------------------------------------------------------------------- */
/* Material includes */
/* -------------------------------------------------------------------------- */
@AKANTU_MATERIAL_INCLUDES@
/* -------------------------------------------------------------------------- */
/* Material list */
/* -------------------------------------------------------------------------- */
#define AKANTU_MATERIAL_LIST \
@AKANTU_MATERIAL_LISTS@
// leave an empty line after the list
#endif /* __AKANTU_MATERIAL_LIST_HH__ */
diff --git a/src/model/solid_mechanics/material_selector.hh b/src/model/solid_mechanics/material_selector.hh
index 48295573c..e96465617 100644
--- a/src/model/solid_mechanics/material_selector.hh
+++ b/src/model/solid_mechanics/material_selector.hh
@@ -1,146 +1,146 @@
/**
* @file material_selector.hh
*
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Thu Dec 17 2015
*
* @brief class describing how to choose a material for a given element
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_SELECTOR_HH__
#define __AKANTU_MATERIAL_SELECTOR_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class SolidMechanicsModel;
/**
* main class to assign same or different materials for different
* elements
*/
class MaterialSelector {
public:
MaterialSelector() : fallback_value(0) {}
virtual ~MaterialSelector() {}
virtual UInt operator()(const Element & element) {
return fallback_value;
}
void setFallback(UInt f) { fallback_value = f; }
protected:
UInt fallback_value;
};
/* -------------------------------------------------------------------------- */
/**
* class that assigns the first material to regular elements by default
*/
class DefaultMaterialSelector : public MaterialSelector {
public:
DefaultMaterialSelector(const ElementTypeMapArray<UInt> & material_index) :
material_index(material_index) { }
UInt operator()(const Element & element) {
try {
DebugLevel dbl = debug::getDebugLevel();
debug::setDebugLevel(dblError);
const Array<UInt> & mat_indexes = material_index(element.type, element.ghost_type);
UInt mat = this->fallback_value;
if(element.element < mat_indexes.getSize())
mat = mat_indexes(element.element);
debug::setDebugLevel(dbl);
return mat;
} catch (...) {
return MaterialSelector::operator()(element);
}
}
private:
const ElementTypeMapArray<UInt> & material_index;
};
/* -------------------------------------------------------------------------- */
/**
* Use elemental data to assign materials
*/
template<typename T>
class ElementDataMaterialSelector : public MaterialSelector {
public:
ElementDataMaterialSelector(const ElementTypeMapArray<T> & element_data,
const SolidMechanicsModel & model,
UInt first_index = 1):
element_data(element_data),
model(model),
first_index(first_index)
{}
inline T elementData(const Element & element) {
DebugLevel dbl = debug::getDebugLevel();
debug::setDebugLevel(dblError);
T data = element_data(element.type, element.ghost_type)(element.element);
debug::setDebugLevel(dbl);
return data;
}
inline UInt operator() (const Element & element) {
return MaterialSelector::operator()(element);
}
protected:
/// list of element with the specified data (i.e. tag value)
const ElementTypeMapArray<T> & element_data;
/// the model that the materials belong
const SolidMechanicsModel & model;
/// first material index: equal to 1 if none specified
UInt first_index;
};
/* -------------------------------------------------------------------------- */
/**
* class to use mesh data information to assign different materials
* where name is the tag value: tag_0, tag_1
*/
template<typename T>
class MeshDataMaterialSelector : public ElementDataMaterialSelector<T> {
public:
MeshDataMaterialSelector(const std::string & name, const SolidMechanicsModel & model, UInt first_index = 1);
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_SELECTOR_HH__ */
diff --git a/src/model/solid_mechanics/material_selector_tmpl.hh b/src/model/solid_mechanics/material_selector_tmpl.hh
index 35dbdf388..adf4bda9a 100644
--- a/src/model/solid_mechanics/material_selector_tmpl.hh
+++ b/src/model/solid_mechanics/material_selector_tmpl.hh
@@ -1,70 +1,70 @@
/**
* @file material_selector_tmpl.hh
*
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Fri May 1 2015
+ * @date last modification: Fri May 01 2015
*
* @brief Implementation of the template MaterialSelector
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_SELECTOR_TMPL_HH__
#define __AKANTU_MATERIAL_SELECTOR_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<typename T>
MeshDataMaterialSelector<T>::MeshDataMaterialSelector(const std::string & name,
const SolidMechanicsModel & model,
UInt first_index):
ElementDataMaterialSelector<T>(model.getMesh().getData<T>(name), model, first_index)
{}
/* -------------------------------------------------------------------------- */
template<>
inline UInt ElementDataMaterialSelector<std::string>::operator() (const Element & element) {
try {
std::string material_name = this->elementData(element);
return model.getMaterialIndex(material_name);
} catch (...) {
return MaterialSelector::operator()(element);
}
}
/* -------------------------------------------------------------------------- */
template<>
inline UInt ElementDataMaterialSelector<UInt>::operator() (const Element & element) {
try {
return this->elementData(element) - first_index;
} catch (...) {
return MaterialSelector::operator()(element);
}
}
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_SELECTOR_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/internal_field.hh b/src/model/solid_mechanics/materials/internal_field.hh
index 4afe99c2a..ef2c3ecc2 100644
--- a/src/model/solid_mechanics/materials/internal_field.hh
+++ b/src/model/solid_mechanics/materials/internal_field.hh
@@ -1,256 +1,257 @@
/**
* @file internal_field.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Material internal properties
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "element_type_map.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTERNAL_FIELD_HH__
#define __AKANTU_INTERNAL_FIELD_HH__
__BEGIN_AKANTU__
class Material;
class FEEngine;
/**
* class for the internal fields of materials
* to store values for each quadrature
*/
template <typename T> class InternalField : public ElementTypeMapArray<T> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
InternalField(const ID & id, Material & material);
virtual ~InternalField();
/// This constructor is only here to let cohesive elements compile
InternalField(const ID & id, Material & material, FEEngine & fem,
const ElementTypeMapArray<UInt> & element_filter);
/// More general constructor
InternalField(const ID & id, Material & material, UInt dim, FEEngine & fem,
const ElementTypeMapArray<UInt> & element_filter);
InternalField(const ID & id, const InternalField<T> & other);
private:
InternalField operator=(__attribute__((unused))
const InternalField & other){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// function to reset the FEEngine for the internal field
virtual void setFEEngine(FEEngine & fe_engine);
/// function to reset the element kind for the internal
virtual void setElementKind(ElementKind element_kind);
/// initialize the field to a given number of component
virtual void initialize(UInt nb_component);
/// activate the history of this field
virtual void initializeHistory();
/// resize the arrays and set the new element to 0
virtual void resize();
/// set the field to a given value v
virtual void setDefaultValue(const T & v);
/// reset all the fields to the default value
virtual void reset();
/// save the current values in the history
virtual void saveCurrentValues();
/// remove the quadrature points corresponding to suppressed elements
virtual void
removeIntegrationPoints(const ElementTypeMapArray<UInt> & new_numbering);
/// print the content
virtual void printself(std::ostream & stream, int indent = 0) const;
/// get the default value
inline operator T() const;
virtual FEEngine & getFEEngine() { return *fem; }
virtual const FEEngine & getFEEngine() const { return *fem; }
/// AKANTU_GET_MACRO(FEEngine, *fem, FEEngine &);
protected:
/// initialize the arrays in the ElementTypeMapArray<T>
void internalInitialize(UInt nb_component);
/// set the values for new internals
virtual void setArrayValues(T * begin, T * end);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
typedef typename ElementTypeMapArray<T>::type_iterator type_iterator;
typedef typename ElementTypeMapArray<UInt>::type_iterator filter_type_iterator;
/// get the type iterator on all types contained in the internal field
type_iterator firstType(const GhostType & ghost_type = _not_ghost) const {
return ElementTypeMapArray<T>::firstType(this->spatial_dimension, ghost_type,
this->element_kind);
}
/// get the type iterator on the last type contained in the internal field
type_iterator lastType(const GhostType & ghost_type = _not_ghost) const {
return ElementTypeMapArray<T>::lastType(this->spatial_dimension, ghost_type,
this->element_kind);
}
/// get the type iterator on all types contained in the internal field
filter_type_iterator filterFirstType(const GhostType & ghost_type = _not_ghost) const {
return this->element_filter.firstType(this->spatial_dimension, ghost_type,
this->element_kind);
}
/// get the type iterator on the last type contained in the internal field
filter_type_iterator filterLastType(const GhostType & ghost_type = _not_ghost) const {
return this->element_filter.lastType(this->spatial_dimension, ghost_type,
this->element_kind);
}
/// get the array for a given type of the element_filter
const Array<UInt> getFilter(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
return this->element_filter(type, ghost_type);
}
/// get the Array corresponding to the type en ghost_type specified
virtual Array<T> & operator()(const ElementType & type,
const GhostType & ghost_type = _not_ghost) {
return ElementTypeMapArray<T>::operator()(type, ghost_type);
}
virtual const Array<T> &
operator()(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
return ElementTypeMapArray<T>::operator()(type, ghost_type);
}
virtual Array<T> & previous(const ElementType & type,
const GhostType & ghost_type = _not_ghost) {
AKANTU_DEBUG_ASSERT(previous_values != NULL,
"The history of the internal "
<< this->getID() << " has not been activated");
return this->previous_values->operator()(type, ghost_type);
}
virtual const Array<T> &
previous(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
AKANTU_DEBUG_ASSERT(previous_values != NULL,
"The history of the internal "
<< this->getID() << " has not been activated");
return this->previous_values->operator()(type, ghost_type);
}
virtual InternalField<T> & previous() {
AKANTU_DEBUG_ASSERT(previous_values != NULL,
"The history of the internal "
<< this->getID() << " has not been activated");
return *(this->previous_values);
}
virtual const InternalField<T> & previous() const {
AKANTU_DEBUG_ASSERT(previous_values != NULL,
"The history of the internal "
<< this->getID() << " has not been activated");
return *(this->previous_values);
}
/// check if the history is used or not
bool hasHistory() const { return (previous_values != NULL); }
/// get the kind treated by the internal
const ElementKind & getElementKind() const { return element_kind; }
/// return the number of components
UInt getNbComponent() const { return nb_component; }
/// return the spatial dimension corresponding to the internal element type
/// loop filter
UInt getSpatialDimension() const { return this->spatial_dimension; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the material for which this is an internal parameter
Material & material;
/// the fem containing the mesh and the element informations
FEEngine * fem;
/// Element filter if needed
const ElementTypeMapArray<UInt> & element_filter;
/// default value
T default_value;
/// spatial dimension of the element to consider
UInt spatial_dimension;
/// ElementKind of the element to consider
ElementKind element_kind;
/// Number of component of the internal field
UInt nb_component;
/// Is the field initialized
bool is_init;
/// previous values
InternalField<T> * previous_values;
};
/// standard output stream operator
template <typename T>
inline std::ostream & operator<<(std::ostream & stream,
const InternalField<T> & _this) {
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_INTERNAL_FIELD_HH__ */
diff --git a/src/model/solid_mechanics/materials/internal_field_tmpl.hh b/src/model/solid_mechanics/materials/internal_field_tmpl.hh
index 61fff3d1f..9488faa58 100644
--- a/src/model/solid_mechanics/materials/internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/internal_field_tmpl.hh
@@ -1,320 +1,320 @@
/**
* @file internal_field_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief Material internal properties
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTERNAL_FIELD_TMPL_HH__
#define __AKANTU_INTERNAL_FIELD_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <typename T>
InternalField<T>::InternalField(const ID & id, Material & material)
: ElementTypeMapArray<T>(id, material.getID(), material.getMemoryID()),
material(material), fem(&(material.getModel().getFEEngine())),
element_filter(material.getElementFilter()), default_value(T()),
spatial_dimension(material.getModel().getSpatialDimension()),
element_kind(_ek_regular), nb_component(0), is_init(false),
previous_values(NULL) {}
/* -------------------------------------------------------------------------- */
template <typename T>
InternalField<T>::InternalField(
const ID & id, Material & material, FEEngine & fem,
const ElementTypeMapArray<UInt> & element_filter)
: ElementTypeMapArray<T>(id, material.getID(), material.getMemoryID()),
material(material), fem(&fem), element_filter(element_filter),
default_value(T()), spatial_dimension(material.getSpatialDimension()),
element_kind(_ek_regular), nb_component(0), is_init(false),
previous_values(NULL) {}
/* -------------------------------------------------------------------------- */
template <typename T>
InternalField<T>::InternalField(
const ID & id, Material & material, UInt dim, FEEngine & fem,
const ElementTypeMapArray<UInt> & element_filter)
: ElementTypeMapArray<T>(id, material.getID(), material.getMemoryID()),
material(material), fem(&fem), element_filter(element_filter),
default_value(T()), spatial_dimension(dim), element_kind(_ek_regular),
nb_component(0), is_init(false), previous_values(NULL) {}
/* -------------------------------------------------------------------------- */
template <typename T>
InternalField<T>::InternalField(const ID & id, const InternalField<T> & other)
: ElementTypeMapArray<T>(id, other.material.getID(),
other.material.getMemoryID()),
material(other.material), fem(other.fem),
element_filter(other.element_filter), default_value(other.default_value),
spatial_dimension(other.spatial_dimension),
element_kind(other.element_kind), nb_component(other.nb_component),
is_init(false), previous_values(NULL) {
AKANTU_DEBUG_ASSERT(other.is_init,
"Cannot create a copy of a non initialized field");
this->internalInitialize(this->nb_component);
}
/* -------------------------------------------------------------------------- */
template <typename T> InternalField<T>::~InternalField() {
if (this->is_init) {
this->material.unregisterInternal(*this);
}
delete previous_values;
}
/* -------------------------------------------------------------------------- */
template <typename T> void InternalField<T>::setFEEngine(FEEngine & fe_engine) {
this->fem = &fe_engine;
}
/* -------------------------------------------------------------------------- */
template <typename T>
void InternalField<T>::setElementKind(ElementKind element_kind) {
this->element_kind = element_kind;
}
/* -------------------------------------------------------------------------- */
template <typename T> void InternalField<T>::initialize(UInt nb_component) {
internalInitialize(nb_component);
}
/* -------------------------------------------------------------------------- */
template <typename T> void InternalField<T>::initializeHistory() {
if (!previous_values)
previous_values = new InternalField<T>("previous_" + this->getID(), *this);
}
/* -------------------------------------------------------------------------- */
template <typename T> void InternalField<T>::resize() {
if (!this->is_init)
return;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
filter_type_iterator it = this->filterFirstType(*gt);
filter_type_iterator end = this->filterLastType(*gt);
for (; it != end; ++it) {
UInt nb_element = this->element_filter(*it, *gt).getSize();
UInt nb_quadrature_points = this->fem->getNbIntegrationPoints(*it, *gt);
UInt new_size = nb_element * nb_quadrature_points;
UInt old_size = 0;
Array<T> * vect = NULL;
if (this->exists(*it, *gt)) {
vect = &(this->operator()(*it, *gt));
old_size = vect->getSize();
vect->resize(new_size);
} else {
vect = &(this->alloc(nb_element * nb_quadrature_points, nb_component,
*it, *gt));
}
this->setArrayValues(vect->storage() + old_size * vect->getNbComponent(),
vect->storage() + new_size * vect->getNbComponent());
}
}
}
/* -------------------------------------------------------------------------- */
template <typename T> void InternalField<T>::setDefaultValue(const T & value) {
this->default_value = value;
this->reset();
}
/* -------------------------------------------------------------------------- */
template <typename T> void InternalField<T>::reset() {
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
type_iterator it = this->firstType(*gt);
type_iterator end = this->lastType(*gt);
for (; it != end; ++it) {
Array<T> & vect = this->operator()(*it, *gt);
vect.clear();
this->setArrayValues(vect.storage(),
vect.storage() +
vect.getSize() * vect.getNbComponent());
}
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
void InternalField<T>::internalInitialize(UInt nb_component) {
if (!this->is_init) {
this->nb_component = nb_component;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
filter_type_iterator it = this->filterFirstType(*gt);
filter_type_iterator end = this->filterLastType(*gt);
for (; it != end; ++it) {
UInt nb_element = this->element_filter(*it, *gt).getSize();
UInt nb_quadrature_points = this->fem->getNbIntegrationPoints(*it, *gt);
if (this->exists(*it, *gt))
this->operator()(*it, *gt).resize(nb_element * nb_quadrature_points);
else
this->alloc(nb_element * nb_quadrature_points, nb_component, *it,
*gt);
}
}
this->material.registerInternal(*this);
this->is_init = true;
}
this->reset();
if (this->previous_values)
this->previous_values->internalInitialize(nb_component);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void InternalField<T>::setArrayValues(T * begin, T * end) {
for (; begin < end; ++begin)
*begin = this->default_value;
}
/* -------------------------------------------------------------------------- */
template <typename T> void InternalField<T>::saveCurrentValues() {
AKANTU_DEBUG_ASSERT(this->previous_values != NULL,
"The history of the internal "
<< this->getID() << " has not been activated");
if (!this->is_init)
return;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
type_iterator it = this->firstType(*gt);
type_iterator end = this->lastType(*gt);
for (; it != end; ++it) {
this->previous_values->operator()(*it, *gt)
.copy(this->operator()(*it, *gt));
}
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
void InternalField<T>::removeIntegrationPoints(
const ElementTypeMapArray<UInt> & new_numbering) {
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
ElementTypeMapArray<UInt>::type_iterator it =
new_numbering.firstType(_all_dimensions, *gt, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end =
new_numbering.lastType(_all_dimensions, *gt, _ek_not_defined);
for (; it != end; ++it) {
ElementType type = *it;
if (this->exists(type, *gt)) {
Array<T> & vect = this->operator()(type, *gt);
if (!vect.getSize())
continue;
const Array<UInt> & renumbering = new_numbering(type, *gt);
UInt nb_quad_per_elem = fem->getNbIntegrationPoints(type, *gt);
UInt nb_component = vect.getNbComponent();
Array<T> tmp(renumbering.getSize() * nb_quad_per_elem, nb_component);
AKANTU_DEBUG_ASSERT(
tmp.getSize() == vect.getSize(),
"Something strange append some mater was created from nowhere!!");
AKANTU_DEBUG_ASSERT(
tmp.getSize() == vect.getSize(),
"Something strange append some mater was created or disappeared in "
<< vect.getID() << "(" << vect.getSize()
<< "!=" << tmp.getSize() << ") "
"!!");
UInt new_size = 0;
for (UInt i = 0; i < renumbering.getSize(); ++i) {
UInt new_i = renumbering(i);
if (new_i != UInt(-1)) {
memcpy(tmp.storage() + new_i * nb_component * nb_quad_per_elem,
vect.storage() + i * nb_component * nb_quad_per_elem,
nb_component * nb_quad_per_elem * sizeof(T));
++new_size;
}
}
tmp.resize(new_size * nb_quad_per_elem);
vect.copy(tmp);
}
}
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
void InternalField<T>::printself(std::ostream & stream, int indent) const {
stream << "InternalField [ " << this->getID();
#if !defined(AKANTU_NDEBUG)
if (AKANTU_DEBUG_TEST(dblDump)) {
stream << std::endl;
ElementTypeMapArray<T>::printself(stream, indent + 3);
} else {
#endif
stream << " {" << this->getData(_not_ghost).size() << " types - "
<< this->getData(_ghost).size() << " ghost types"
<< "}";
#if !defined(AKANTU_NDEBUG)
}
#endif
stream << " ]";
}
/* -------------------------------------------------------------------------- */
template <>
inline void ParsableParamTyped<InternalField<Real> >::parseParam(
const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
Real r = in_param;
param.setDefaultValue(r);
}
/* -------------------------------------------------------------------------- */
template <typename T> inline InternalField<T>::operator T() const {
return default_value;
}
__END_AKANTU__
#endif /* __AKANTU_INTERNAL_FIELD_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/cohesive_internal_field.hh b/src/model/solid_mechanics/materials/material_cohesive/cohesive_internal_field.hh
index 926073b60..b8835bf54 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/cohesive_internal_field.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/cohesive_internal_field.hh
@@ -1,69 +1,70 @@
/**
* @file cohesive_internal_field.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Jul 29 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 08 2015
*
* @brief Internal field for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "internal_field.hh"
#ifndef __AKANTU_COHESIVE_INTERNAL_FIELD_HH__
#define __AKANTU_COHESIVE_INTERNAL_FIELD_HH__
__BEGIN_AKANTU__
/// internal field class for cohesive materials
template<typename T>
class CohesiveInternalField : public InternalField<T> {
public:
CohesiveInternalField(const ID & id, Material & material);
virtual ~CohesiveInternalField();
/// initialize the field to a given number of component
void initialize(UInt nb_component);
private:
CohesiveInternalField operator=(__attribute__((unused)) const CohesiveInternalField & other) {};
};
/* -------------------------------------------------------------------------- */
/* Facet Internal Field */
/* -------------------------------------------------------------------------- */
template<typename T>
class FacetInternalField : public InternalField<T> {
public:
FacetInternalField(const ID & id, Material & material);
virtual ~FacetInternalField();
/// initialize the field to a given number of component
void initialize(UInt nb_component);
};
__END_AKANTU__
#endif /* __AKANTU_COHESIVE_INTERNAL_FIELD_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/cohesive_internal_field_tmpl.hh b/src/model/solid_mechanics/materials/material_cohesive/cohesive_internal_field_tmpl.hh
index cb3bbf8f5..27a317e53 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/cohesive_internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/cohesive_internal_field_tmpl.hh
@@ -1,91 +1,91 @@
/**
* @file cohesive_internal_field_tmpl.hh
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Tue Jul 29 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief implementation of the cohesive internal field
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COHESIVE_INTERNAL_FIELD_TMPL_HH__
#define __AKANTU_COHESIVE_INTERNAL_FIELD_TMPL_HH__
__BEGIN_AKANTU__
template<typename T>
CohesiveInternalField<T>::CohesiveInternalField(const ID & id, Material & material) :
InternalField<T>(id, material, material.getModel().getFEEngine("CohesiveFEEngine"),
dynamic_cast<MaterialCohesive &>(material).getElementFilter()) {
this->element_kind = _ek_cohesive;
}
template<typename T>
CohesiveInternalField<T>::~CohesiveInternalField() { };
template<typename T>
void CohesiveInternalField<T>::initialize(UInt nb_component) {
this->internalInitialize(nb_component);
}
/* -------------------------------------------------------------------------- */
template<typename T>
FacetInternalField<T>::FacetInternalField(const ID & id, Material & material) :
InternalField<T>(id, material, material.getModel().getFEEngine("FacetsFEEngine"),
dynamic_cast<MaterialCohesive &>(material).getFacetFilter()) {
this->spatial_dimension -= 1;
this->element_kind = _ek_regular;
}
template<typename T>
FacetInternalField<T>::~FacetInternalField() { };
template<typename T>
void FacetInternalField<T>::initialize(UInt nb_component) {
this->internalInitialize(nb_component);
}
/* -------------------------------------------------------------------------- */
template<>
inline void ParsableParamTyped< RandomInternalField<Real, FacetInternalField> >::parseParam(const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
RandomParameter<Real> r = in_param;
param.setRandomDistribution(r);
}
/* -------------------------------------------------------------------------- */
template<>
inline void ParsableParamTyped< RandomInternalField<Real, CohesiveInternalField> >::parseParam(const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
RandomParameter<Real> r = in_param;
param.setRandomDistribution(r);
}
__END_AKANTU__
#endif /* __AKANTU_COHESIVE_INTERNAL_FIELD_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc
index 55afde9c6..eb91a47ec 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc
@@ -1,210 +1,211 @@
/**
* @file material_cohesive_bilinear.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Feb 22 2012
- * @date last modification: Thu Jul 31 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Bilinear cohesive constitutive law
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_cohesive_bilinear.hh"
#include "solid_mechanics_model_cohesive.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialCohesiveBilinear<spatial_dimension>::MaterialCohesiveBilinear(SolidMechanicsModel & model, const ID & id) :
MaterialCohesiveLinear<spatial_dimension>(model, id) {
AKANTU_DEBUG_IN();
this->registerParam("delta_0", delta_0, Real(0.),
_pat_parsable | _pat_readable,
"Elastic limit displacement");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveBilinear<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
this->sigma_c_eff.setRandomDistribution(this->sigma_c.getRandomParameter());
MaterialCohesiveLinear<spatial_dimension>::initMaterial();
this->delta_max .setDefaultValue(delta_0);
this->insertion_stress.setDefaultValue(0);
this->delta_max .reset();
this->insertion_stress.reset();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveBilinear<spatial_dimension>::onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event) {
AKANTU_DEBUG_IN();
MaterialCohesiveLinear<spatial_dimension>::onElementsAdded(element_list, event);
bool scale_traction = false;
// don't scale sigma_c if volume_s hasn't been specified by the user
if (!Math::are_float_equal(this->volume_s, 0.)) scale_traction = true;
Array<Element>::const_scalar_iterator el_it = element_list.begin();
Array<Element>::const_scalar_iterator el_end = element_list.end();
for (; el_it != el_end; ++el_it) {
// filter not ghost cohesive elements
if (el_it->ghost_type != _not_ghost || el_it->kind != _ek_cohesive) continue;
UInt index = el_it->element;
ElementType type = el_it->type;
UInt nb_element = this->model->getMesh().getNbElement(type);
UInt nb_quad_per_element = this->fem_cohesive->getNbIntegrationPoints(type);
Array<Real>::vector_iterator sigma_c_begin
= this->sigma_c_eff(type).begin_reinterpret(nb_quad_per_element, nb_element);
Vector<Real> sigma_c_vec = sigma_c_begin[index];
Array<Real>::vector_iterator delta_c_begin
= this->delta_c_eff(type).begin_reinterpret(nb_quad_per_element, nb_element);
Vector<Real> delta_c_vec = delta_c_begin[index];
if (scale_traction) scaleTraction(*el_it, sigma_c_vec);
/**
* Recompute sigma_c as
* @f$ {\sigma_c}_\textup{new} =
* \frac{{\sigma_c}_\textup{old} \delta_c} {\delta_c - \delta_0} @f$
*/
for (UInt q = 0; q < nb_quad_per_element; ++q) {
delta_c_vec(q) = 2 * this->G_c / sigma_c_vec(q);
if (delta_c_vec(q) - delta_0 < Math::getTolerance())
AKANTU_DEBUG_ERROR("delta_0 = " << delta_0 <<
" must be lower than delta_c = " << delta_c_vec(q)
<< ", modify your material file");
sigma_c_vec(q) *= delta_c_vec(q) / (delta_c_vec(q) - delta_0);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveBilinear<spatial_dimension>::scaleTraction(const Element & el,
Vector<Real> & sigma_c_vec) {
AKANTU_DEBUG_IN();
Real base_sigma_c = this->sigma_c_eff;
const Mesh & mesh_facets = this->model->getMeshFacets();
const FEEngine & fe_engine = this->model->getFEEngine();
Array<Element>::const_vector_iterator coh_element_to_facet_begin
= mesh_facets.getSubelementToElement(el.type).begin(2);
const Vector<Element> & coh_element_to_facet
= coh_element_to_facet_begin[el.element];
// compute bounding volume
Real volume = 0;
// loop over facets
for (UInt f = 0; f < 2; ++f) {
const Element & facet = coh_element_to_facet(f);
const Array< std::vector<Element> > & facet_to_element
= mesh_facets.getElementToSubelement(facet.type, facet.ghost_type);
const std::vector<Element> & element_list = facet_to_element(facet.element);
std::vector<Element>::const_iterator elem = element_list.begin();
std::vector<Element>::const_iterator elem_end = element_list.end();
// loop over elements connected to each facet
for (; elem != elem_end; ++elem) {
// skip cohesive elements and dummy elements
if (*elem == ElementNull || elem->kind == _ek_cohesive) continue;
// unit vector for integration in order to obtain the volume
UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(elem->type);
Vector<Real> unit_vector(nb_quadrature_points, 1);
volume += fe_engine.integrate(unit_vector, elem->type,
elem->element, elem->ghost_type);
}
}
// scale sigma_c
sigma_c_vec -= base_sigma_c;
sigma_c_vec *= std::pow(this->volume_s / volume, 1. / this->m_s);
sigma_c_vec += base_sigma_c;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveBilinear<spatial_dimension>::computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialCohesiveLinear<spatial_dimension>::computeTraction(normal,
el_type,
ghost_type);
// adjust damage
Array<Real>::scalar_iterator delta_c_it
= this->delta_c_eff(el_type, ghost_type).begin();
Array<Real>::scalar_iterator delta_max_it
= this->delta_max(el_type, ghost_type).begin();
Array<Real>::scalar_iterator damage_it
= this->damage(el_type, ghost_type).begin();
Array<Real>::scalar_iterator damage_end
= this->damage(el_type, ghost_type).end();
for (; damage_it != damage_end; ++damage_it, ++delta_max_it, ++delta_c_it) {
*damage_it = std::max((*delta_max_it - delta_0) / (*delta_c_it - delta_0), Real(0.));
*damage_it = std::min(*damage_it, Real(1.));
}
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialCohesiveBilinear);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh
index 86b840e75..17e11e33c 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh
@@ -1,112 +1,113 @@
/**
* @file material_cohesive_bilinear.hh
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Wed Feb 22 2012
- * @date last modification: Tue Jul 29 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Bilinear cohesive constitutive law
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_cohesive_linear.hh"
#ifndef __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__
#define __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
* Cohesive material bilinear
*
* parameters in the material files :
* - delta_0 : elastic limit displacement (default: 0)
* - sigma_c : critical stress sigma_c (default: 0)
* - beta : weighting parameter for sliding and normal opening (default: 0)
* - G_cI : fracture energy for mode I (default: 0)
* - G_cII : fracture energy for mode II (default: 0)
* - penalty : stiffness in compression to prevent penetration
*/
template<UInt spatial_dimension>
class MaterialCohesiveBilinear : public MaterialCohesiveLinear<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialCohesiveBilinear(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material computed parameter
virtual void initMaterial();
/// set material parameters for new elements
virtual void onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event);
protected:
/// constitutive law
void computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type = _not_ghost);
/**
* Scale traction sigma_c according to the volume of the
* two elements surrounding an element
*/
void scaleTraction(const Element & el, Vector<Real> & sigma_c_vec);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// elastic limit displacement
Real delta_0;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "material_cohesive_elastic_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.cc
index 7b3b59faa..7c3f1ec9e 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.cc
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.cc
@@ -1,362 +1,363 @@
/**
* @file material_cohesive_exponential.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Mon Jul 09 2012
- * @date last modification: Fri Mar 21 2014
+ * @date last modification: Tue Aug 04 2015
*
* @brief Exponential irreversible cohesive law of mixed mode loading
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_cohesive_exponential.hh"
#include "solid_mechanics_model.hh"
#include "sparse_matrix.hh"
#include "dof_synchronizer.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialCohesiveExponential<spatial_dimension>::MaterialCohesiveExponential(SolidMechanicsModel & model,
const ID & id) :
MaterialCohesive(model,id) {
AKANTU_DEBUG_IN();
this->registerParam("beta" , beta , Real(0.) , _pat_parsable, "Beta parameter");
this->registerParam("exponential_penalty", exp_penalty, true,
_pat_parsable, "Is contact penalty following the exponential law?" );
this->registerParam("contact_tangent", contact_tangent, Real(1.0),
_pat_parsable, "Ratio of contact tangent over the initial exponential tangent" );
// this->initInternalArray(delta_max, 1, _ek_cohesive);
use_previous_delta_max=true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialCohesive::initMaterial();
if ((exp_penalty)&&(contact_tangent!=1)){
contact_tangent = 1;
AKANTU_DEBUG_WARNING("The parsed paramter <contact_tangent> is forced to 1.0 when the contact penalty follows the exponential law");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
Array<Real>::vector_iterator traction_it =
tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_it =
opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::const_vector_iterator normal_it =
normal.begin(spatial_dimension);
Array<Real>::vector_iterator traction_end =
tractions(el_type, ghost_type).end(spatial_dimension);
Array<Real>::iterator<Real> delta_max_it =
delta_max(el_type, ghost_type).begin();
Array<Real>::iterator<Real> delta_max_prev_it =
delta_max.previous(el_type, ghost_type).begin();
/// compute scalars
Real beta2 = beta*beta;
/// loop on each quadrature point
for (; traction_it != traction_end;
++traction_it, ++opening_it, ++normal_it, ++delta_max_it, ++delta_max_prev_it) {
/// compute normal and tangential opening vectors
Real normal_opening_norm = opening_it->dot(*normal_it);
Vector<Real> normal_opening(spatial_dimension);
normal_opening = (*normal_it);
normal_opening *= normal_opening_norm;
Vector<Real> tangential_opening(spatial_dimension);
tangential_opening = *opening_it;
tangential_opening -= normal_opening;
Real tangential_opening_norm = tangential_opening.norm();
/**
* compute effective opening displacement
* @f$ \delta = \sqrt{
* \beta^2 \Delta_t^2 + \Delta_n^2 } @f$
*/
Real delta = tangential_opening_norm;
delta *= delta * beta2;
delta += normal_opening_norm * normal_opening_norm;
delta = sqrt(delta);
if ((normal_opening_norm<0) && (std::abs(normal_opening_norm) > Math::getTolerance())) {
Vector<Real> op_n(*opening_it);
op_n *= *normal_it;
Vector<Real> delta_s(*opening_it);
delta_s -= op_n;
delta = tangential_opening_norm*beta;
computeCoupledTraction(*traction_it, *normal_it, delta, delta_s,
*delta_max_it, *delta_max_prev_it);
computeCompressiveTraction(*traction_it, *normal_it, normal_opening_norm,
*opening_it);
}
else computeCoupledTraction(*traction_it, *normal_it, delta, *opening_it,
*delta_max_it, *delta_max_prev_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTraction(Vector<Real> & tract,
const Vector<Real> & normal,
Real delta,
const Vector<Real> & opening,
Real & delta_max_new,
Real delta_max) {
AKANTU_DEBUG_IN();
/// full damage case
if (std::abs(delta) < Math::getTolerance()) {
/// set traction to zero
tract.clear();
} else { /// element not fully damaged
/**
* Compute traction loading @f$ \mathbf{T} =
* e \sigma_c \frac{\delta}{\delta_c} e^{-\delta/ \delta_c}@f$
*/
/**
* Compute traction unloading @f$ \mathbf{T} =
* \frac{t_{max}}{\delta_{max}} \delta @f$
*/
Real beta2 = beta*beta;
Vector<Real> op_n_n(opening);
op_n_n*=normal;
op_n_n*=(1-beta2);
op_n_n*=normal;
tract = beta2*opening;
tract += op_n_n;
delta_max_new = std::max(delta_max, delta);
tract *= exp(1)*sigma_c*exp(- delta_max_new / delta_c)/delta_c;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCompressiveTraction(Vector<Real> & tract,
const Vector<Real> & normal,
Real delta_n,
const Vector<Real> & opening) {
Vector<Real> temp_tract(normal);
if(exp_penalty) {
temp_tract *= delta_n*exp(1)*sigma_c*exp(- delta_n / delta_c)/delta_c;
}
else {
Real initial_tg = contact_tangent*exp(1)*sigma_c*delta_n/delta_c;
temp_tract *= initial_tg;
}
tract += temp_tract;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::matrix_iterator tangent_it = tangent_matrix.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator tangent_end = tangent_matrix.end(spatial_dimension, spatial_dimension);
Array<Real>::const_vector_iterator normal_it = normal.begin(spatial_dimension);
Array<Real>::vector_iterator opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator traction_it = tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::iterator<Real>delta_max_it = delta_max.previous(el_type, ghost_type).begin();
Real beta2 = beta*beta;
/**
* compute tangent matrix @f$ \frac{\partial \mathbf{t}}
* {\partial \delta} = \hat{\mathbf{t}} \otimes
* \frac{\partial (t/\delta)}{\partial \delta}
* \frac{\hat{\mathbf{t}}}{\delta}+ \frac{t}{\delta} [ \beta^2 \mathbf{I} +
* (1-\beta^2) (\mathbf{n} \otimes \mathbf{n})] @f$
**/
/**
* In which @f$
* \frac{\partial(t/ \delta)}{\partial \delta} =
* \left\{\begin{array} {l l}
* -e \frac{\sigma_c}{\delta_c^2 }e^{-\delta / \delta_c} & \quad if
* \delta \geq \delta_{max} \\
* 0 & \quad if \delta < \delta_{max}, \delta_n > 0
* \end{array}\right. @f$
**/
for (; tangent_it != tangent_end; ++tangent_it, ++normal_it, ++opening_it, ++traction_it, ++ delta_max_it) {
Real normal_opening_norm = opening_it->dot(*normal_it);
Vector<Real> normal_opening(spatial_dimension);
normal_opening = (*normal_it);
normal_opening *= normal_opening_norm;
Vector<Real> tangential_opening(spatial_dimension);
tangential_opening = *opening_it;
tangential_opening -= normal_opening;
Real tangential_opening_norm = tangential_opening.norm();
Real delta = tangential_opening_norm;
delta *= delta * beta2;
delta += normal_opening_norm * normal_opening_norm;
delta = sqrt(delta);
if ((normal_opening_norm<0) && (std::abs(normal_opening_norm) > Math::getTolerance())) {
Vector<Real> op_n(*opening_it);
op_n *= *normal_it;
Vector<Real> delta_s(*opening_it);
delta_s -= op_n;
delta = tangential_opening_norm*beta;
computeCoupledTangent(*tangent_it, *traction_it, *normal_it, delta,
delta_s, *delta_max_it);
computeCompressivePenalty(*tangent_it, *normal_it, normal_opening_norm);
}
else computeCoupledTangent(*tangent_it, *traction_it, *normal_it, delta,
*opening_it, *delta_max_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTangent(Matrix<Real> & tangent,
Vector<Real> tract,
const Vector<Real> & normal,
Real delta,
const Vector<Real> & opening,
Real delta_max_new) {
AKANTU_DEBUG_IN();
Real beta2 = beta*beta;
Matrix<Real> I(spatial_dimension, spatial_dimension);
I.eye(beta2);
Matrix<Real> nn(spatial_dimension, spatial_dimension);
nn.outerProduct(normal, normal);
nn *= (1-beta2);
I += nn;
if(std::abs(delta) < Math::getTolerance()){
I *= exp(1)*sigma_c/delta_c;
tangent += I;
} else {
Real traction_norm = tract.norm();
Vector<Real> t_hat(opening);
Vector<Real> beta2delta(opening);
beta2delta *= beta2;
t_hat *= normal;
t_hat *= (beta2-1);
t_hat *= normal;
t_hat += beta2delta;
Vector<Real> deriv_t_hat(t_hat);
deriv_t_hat /= delta;
Real derivatives = 0;
if ((delta > delta_max_new) || (std::abs(delta - delta_max_new) < 1e-12)) {
derivatives = -exp(1- delta/delta_c)*sigma_c/(delta_c*delta_c);
}
deriv_t_hat *= derivatives;
Matrix<Real> t_var_t(spatial_dimension, spatial_dimension);
t_var_t.outerProduct(t_hat, deriv_t_hat);
I *= traction_norm / delta;
tangent += t_var_t;
tangent += I;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCompressivePenalty(Matrix<Real> & tangent,
const Vector<Real> & normal,
Real delta_n) {
if (!exp_penalty) delta_n=0;
Matrix<Real> n_outer_n(spatial_dimension,spatial_dimension);
n_outer_n.outerProduct(normal,normal);
Real normal_tg = contact_tangent*exp(1)*sigma_c*exp(-delta_n/delta_c)*(1-delta_n/delta_c)/delta_c;
n_outer_n *= normal_tg;
tangent += n_outer_n;
}
INSTANTIATE_MATERIAL(MaterialCohesiveExponential);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.hh
index 6bfdb33d3..942c138ed 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.hh
@@ -1,126 +1,128 @@
/**
* @file material_cohesive_exponential.hh
*
+ * @author Fabian Barras <fabian.barras@epfl.ch>
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Mon Jul 09 2012
- * @date last modification: Mon May 13 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Feb 06 2015
*
* @brief Exponential irreversible cohesive law of mixed mode loading
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_cohesive.hh"
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH__
#define __AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
* Cohesive material Exponential damage
*
* parameters in the material files :
* - sigma_c : critical stress sigma_c (default: 0)
* - beta : weighting parameter for sliding and normal opening (default: 0)
* - delta_c : critical opening (default: 0)
*/
template<UInt spatial_dimension>
class MaterialCohesiveExponential : public MaterialCohesive {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialCohesiveExponential(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
/// Initialization
void initMaterial();
/// constitutive law
void computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type = _not_ghost);
/// compute the tangent stiffness matrix for an element type
void computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type = _not_ghost);
private:
void computeCoupledTraction(Vector<Real> & tract, const Vector<Real> & normal,
Real delta, const Vector<Real> & opening,
Real & delta_max_new, Real delta_max);
void computeCompressiveTraction(Vector<Real> & tract, const Vector<Real> & normal,
Real delta_n, const Vector<Real> & opening);
void computeCoupledTangent(Matrix<Real> & tangent, Vector<Real> tract,
const Vector<Real> & normal, Real delta,
const Vector<Real> & opening, Real delta_max_new);
void computeCompressivePenalty(Matrix<Real> & tangent, const Vector<Real> & normal,
Real delta_n);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// beta parameter
Real beta;
/// contact penalty = initial slope ?
bool exp_penalty;
/// Ratio of contact tangent over the initial exponential tangent
Real contact_tangent;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
// #include "material_cohesive_exponential_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc
index 325b064e9..89e0d4b86 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc
@@ -1,753 +1,754 @@
/**
* @file material_cohesive_linear.cc
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Tue May 08 2012
- * @date last modification: Thu Nov 19 2015
+ * @date creation: Wed Feb 22 2012
+ * @date last modification: Thu Jan 14 2016
*
* @brief Linear irreversible cohesive law of mixed mode loading with
* random stress definition for extrinsic type
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <algorithm>
#include <numeric>
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear.hh"
#include "solid_mechanics_model_cohesive.hh"
#include "sparse_matrix.hh"
#include "dof_synchronizer.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialCohesiveLinear<spatial_dimension>::MaterialCohesiveLinear(SolidMechanicsModel & model,
const ID & id) :
MaterialCohesive(model,id),
sigma_c_eff("sigma_c_eff", *this),
delta_c_eff("delta_c_eff", *this),
insertion_stress("insertion_stress", *this),
opening_prec("opening_prec", *this),
residual_sliding("residual_sliding", *this),
friction_force("friction_force", *this),
reduction_penalty("reduction_penalty", *this) {
AKANTU_DEBUG_IN();
this->registerParam("beta", beta, Real(0.),
_pat_parsable | _pat_readable,
"Beta parameter");
this->registerParam("G_c", G_c, Real(0.),
_pat_parsable | _pat_readable,
"Mode I fracture energy");
this->registerParam("penalty", penalty, Real(0.),
_pat_parsable | _pat_readable,
"Penalty coefficient");
this->registerParam("volume_s", volume_s, Real(0.),
_pat_parsable | _pat_readable,
"Reference volume for sigma_c scaling");
this->registerParam("m_s", m_s, Real(1.),
_pat_parsable | _pat_readable,
"Weibull exponent for sigma_c scaling");
this->registerParam("kappa", kappa, Real(1.),
_pat_parsable | _pat_readable,
"Kappa parameter");
this->registerParam("contact_after_breaking", contact_after_breaking, false,
_pat_parsable | _pat_readable,
"Activation of contact when the elements are fully damaged");
this->registerParam("max_quad_stress_insertion", max_quad_stress_insertion, false,
_pat_parsable | _pat_readable,
"Insertion of cohesive element when stress is high enough just on one quadrature point");
this->registerParam("friction", friction, false,
_pat_parsable | _pat_readable,
"Activation of friction in case of contact");
this->registerParam("mu", mu_max, Real(0.),
_pat_parsable | _pat_readable,
"Maximum value of the friction coefficient");
this->registerParam("penalty_for_friction", friction_penalty, Real(0.),
_pat_parsable | _pat_readable,
"Penalty parameter for the friction behavior");
this->registerParam("recompute", recompute, false,
_pat_parsable | _pat_modifiable,
"recompute solution");
this->use_previous_delta_max = true;
this->use_previous_opening = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialCohesive::initMaterial();
/// compute scalars
beta2_kappa2 = beta * beta/kappa/kappa;
beta2_kappa = beta * beta/kappa;
if (Math::are_float_equal(beta, 0))
beta2_inv = 0;
else
beta2_inv = 1./beta/beta;
sigma_c_eff.initialize(1);
delta_c_eff.initialize(1);
insertion_stress.initialize(spatial_dimension);
opening_prec.initialize(spatial_dimension);
friction_force.initialize(spatial_dimension);
residual_sliding.initialize(1);
reduction_penalty.initialize(1);
if (!Math::are_float_equal(delta_c, 0.))
delta_c_eff.setDefaultValue(delta_c);
else
delta_c_eff.setDefaultValue(2 * G_c / sigma_c);
if (model->getIsExtrinsic()) scaleInsertionTraction();
residual_sliding.initializeHistory();
opening_prec.initializeHistory();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::scaleInsertionTraction() {
AKANTU_DEBUG_IN();
// do nothing if volume_s hasn't been specified by the user
if (Math::are_float_equal(volume_s, 0.)) return;
const Mesh & mesh_facets = model->getMeshFacets();
const FEEngine & fe_engine = model->getFEEngine();
const FEEngine & fe_engine_facet = model->getFEEngine("FacetsFEEngine");
// loop over facet type
Mesh::type_iterator first = mesh_facets.firstType(spatial_dimension - 1);
Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1);
Real base_sigma_c = sigma_c;
for(;first != last; ++first) {
ElementType type_facet = *first;
const Array< std::vector<Element> > & facet_to_element
= mesh_facets.getElementToSubelement(type_facet);
UInt nb_facet = facet_to_element.getSize();
UInt nb_quad_per_facet = fe_engine_facet.getNbIntegrationPoints(type_facet);
// iterator to modify sigma_c for all the quadrature points of a facet
Array<Real>::vector_iterator sigma_c_iterator
= sigma_c(type_facet).begin_reinterpret(nb_quad_per_facet, nb_facet);
for (UInt f = 0; f < nb_facet; ++f, ++sigma_c_iterator) {
const std::vector<Element> & element_list = facet_to_element(f);
// compute bounding volume
Real volume = 0;
std::vector<Element>::const_iterator elem = element_list.begin();
std::vector<Element>::const_iterator elem_end = element_list.end();
for (; elem != elem_end; ++elem) {
if (*elem == ElementNull) continue;
// unit vector for integration in order to obtain the volume
UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(elem->type);
Vector<Real> unit_vector(nb_quadrature_points, 1);
volume += fe_engine.integrate(unit_vector, elem->type,
elem->element, elem->ghost_type);
}
// scale sigma_c
*sigma_c_iterator -= base_sigma_c;
*sigma_c_iterator *= std::pow(volume_s / volume, 1. / m_s);
*sigma_c_iterator += base_sigma_c;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::checkInsertion(bool check_only) {
AKANTU_DEBUG_IN();
const Mesh & mesh_facets = model->getMeshFacets();
CohesiveElementInserter & inserter = model->getElementInserter();
Real tolerance = Math::getTolerance();
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1);
Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1);
for (; it != last; ++it) {
ElementType type_facet = *it;
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
const Array<bool> & facets_check = inserter.getCheckFacets(type_facet);
Array<bool> & f_insertion = inserter.getInsertionFacets(type_facet);
Array<UInt> & f_filter = facet_filter(type_facet);
Array<Real> & sig_c_eff = sigma_c_eff(type_cohesive);
Array<Real> & del_c = delta_c_eff(type_cohesive);
Array<Real> & ins_stress = insertion_stress(type_cohesive);
Array<Real> & trac_old = tractions_old(type_cohesive);
Array<Real> & open_prec = opening_prec(type_cohesive);
Array<bool> & red_penalty = reduction_penalty(type_cohesive);
const Array<Real> & f_stress = model->getStressOnFacets(type_facet);
const Array<Real> & sigma_lim = sigma_c(type_facet);
Real max_ratio = 0.;
UInt index_f = 0;
UInt index_filter = 0;
UInt nn = 0;
UInt nb_quad_facet = model->getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
UInt nb_facet = f_filter.getSize();
// if (nb_facet == 0) continue;
Array<Real>::const_iterator<Real> sigma_lim_it = sigma_lim.begin();
Matrix<Real> stress_tmp(spatial_dimension, spatial_dimension);
Matrix<Real> normal_traction(spatial_dimension, nb_quad_facet);
Vector<Real> stress_check(nb_quad_facet);
UInt sp2 = spatial_dimension * spatial_dimension;
const Array<Real> & tangents = model->getTangents(type_facet);
const Array<Real> & normals
= model->getFEEngine("FacetsFEEngine").getNormalsOnIntegrationPoints(type_facet);
Array<Real>::const_vector_iterator normal_begin = normals.begin(spatial_dimension);
Array<Real>::const_vector_iterator tangent_begin = tangents.begin(tangents.getNbComponent());
Array<Real>::const_matrix_iterator facet_stress_begin =
f_stress.begin(spatial_dimension, spatial_dimension * 2);
std::vector<Real> new_sigmas;
std::vector< Vector<Real> > new_normal_traction;
std::vector<Real> new_delta_c;
// loop over each facet belonging to this material
for (UInt f = 0; f < nb_facet; ++f, ++sigma_lim_it) {
UInt facet = f_filter(f);
// skip facets where check shouldn't be realized
if (!facets_check(facet)) continue;
// compute the effective norm on each quadrature point of the facet
for (UInt q = 0; q < nb_quad_facet; ++q) {
UInt current_quad = facet * nb_quad_facet + q;
const Vector<Real> & normal = normal_begin[current_quad];
const Vector<Real> & tangent = tangent_begin[current_quad];
const Matrix<Real> & facet_stress_it = facet_stress_begin[current_quad];
// compute average stress on the current quadrature point
Matrix<Real> stress_1(facet_stress_it.storage(),
spatial_dimension,
spatial_dimension);
Matrix<Real> stress_2(facet_stress_it.storage() + sp2,
spatial_dimension,
spatial_dimension);
stress_tmp.copy(stress_1);
stress_tmp += stress_2;
stress_tmp /= 2.;
Vector<Real> normal_traction_vec(normal_traction(q));
// compute normal and effective stress
stress_check(q) = computeEffectiveNorm(stress_tmp, normal, tangent,
normal_traction_vec);
}
// verify if the effective stress overcomes the threshold
Real final_stress = stress_check.mean();
if (max_quad_stress_insertion)
final_stress = *std::max_element(stress_check.storage(),
stress_check.storage() + nb_quad_facet);
if (final_stress > (*sigma_lim_it - tolerance)) {
if (model->isExplicit()){
f_insertion(facet) = true;
if (!check_only) {
// store the new cohesive material parameters for each quadrature point
for (UInt q = 0; q < nb_quad_facet; ++q) {
Real new_sigma = stress_check(q);
Vector<Real> normal_traction_vec(normal_traction(q));
if (spatial_dimension != 3)
normal_traction_vec *= -1.;
new_sigmas.push_back(new_sigma);
new_normal_traction.push_back(normal_traction_vec);
Real new_delta;
// set delta_c in function of G_c or a given delta_c value
if (Math::are_float_equal(delta_c, 0.))
new_delta = 2 * G_c / new_sigma;
else
new_delta = (*sigma_lim_it) / new_sigma * delta_c;
new_delta_c.push_back(new_delta);
}
}
}else{
Real ratio = final_stress/(*sigma_lim_it);
if (ratio > max_ratio){
++nn;
max_ratio = ratio;
index_f = f;
index_filter = f_filter(f);
}
}
}
}
/// Insertion of only 1 cohesive element in case of implicit approach. The one subjected to the highest stress.
if (!model->isExplicit()){
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Array<Real> abs_max(comm.getNbProc());
abs_max(comm.whoAmI()) = max_ratio;
comm.allGather(abs_max.storage(), 1);
Array<Real>::scalar_iterator it = std::max_element(abs_max.begin(), abs_max.end());
Int pos = it - abs_max.begin();
if (pos != comm.whoAmI()) {
AKANTU_DEBUG_OUT();
return;
}
if (nn) {
f_insertion(index_filter) = true;
if (!check_only) {
// Array<Real>::iterator<Matrix<Real> > normal_traction_it =
// normal_traction.begin_reinterpret(nb_quad_facet, spatial_dimension, nb_facet);
Array<Real>::const_iterator<Real> sigma_lim_it = sigma_lim.begin();
for (UInt q = 0; q < nb_quad_facet; ++q) {
// Vector<Real> ins_s(normal_traction_it[index_f].storage() + q * spatial_dimension,
// spatial_dimension);
Real new_sigma = (sigma_lim_it[index_f]);
Vector<Real> normal_traction_vec(spatial_dimension, 0.0);
new_sigmas.push_back(new_sigma);
new_normal_traction.push_back(normal_traction_vec);
Real new_delta;
//set delta_c in function of G_c or a given delta_c value
if (!Math::are_float_equal(delta_c, 0.))
new_delta = delta_c;
else
new_delta = 2 * G_c / (new_sigma);
new_delta_c.push_back(new_delta);
}
}
}
}
// update material data for the new elements
UInt old_nb_quad_points = sig_c_eff.getSize();
UInt new_nb_quad_points = new_sigmas.size();
sig_c_eff.resize(old_nb_quad_points + new_nb_quad_points);
ins_stress.resize(old_nb_quad_points + new_nb_quad_points);
trac_old.resize(old_nb_quad_points + new_nb_quad_points);
del_c.resize(old_nb_quad_points + new_nb_quad_points);
open_prec.resize(old_nb_quad_points + new_nb_quad_points);
red_penalty.resize(old_nb_quad_points + new_nb_quad_points);
for (UInt q = 0; q < new_nb_quad_points; ++q) {
sig_c_eff(old_nb_quad_points + q) = new_sigmas[q];
del_c(old_nb_quad_points + q) = new_delta_c[q];
red_penalty(old_nb_quad_points + q) = false;
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
ins_stress(old_nb_quad_points + q, dim) = new_normal_traction[q](dim);
trac_old(old_nb_quad_points + q, dim) = new_normal_traction[q](dim);
open_prec(old_nb_quad_points + q, dim) = 0.;
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
Array<Real>::vector_iterator traction_it =
tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_it =
opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_prev_it =
opening.previous(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_prec_it =
opening_prec(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator contact_traction_it =
contact_tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator contact_opening_it =
contact_opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::const_vector_iterator normal_it =
normal.begin(spatial_dimension);
Array<Real>::vector_iterator traction_end =
tractions(el_type, ghost_type).end(spatial_dimension);
Array<Real>::scalar_iterator sigma_c_it =
sigma_c_eff(el_type, ghost_type).begin();
Array<Real>::scalar_iterator delta_max_it =
delta_max(el_type, ghost_type).begin();
Array<Real>::scalar_iterator delta_max_prev_it =
delta_max.previous(el_type, ghost_type).begin();
Array<Real>::scalar_iterator delta_c_it =
delta_c_eff(el_type, ghost_type).begin();
Array<Real>::scalar_iterator damage_it =
damage(el_type, ghost_type).begin();
Array<Real>::vector_iterator insertion_stress_it =
insertion_stress(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::scalar_iterator res_sliding_it =
residual_sliding(el_type, ghost_type).begin();
Array<Real>::scalar_iterator res_sliding_prev_it =
residual_sliding.previous(el_type, ghost_type).begin();
Array<Real>::vector_iterator friction_force_it =
friction_force(el_type, ghost_type).begin(spatial_dimension);
Array<bool>::scalar_iterator reduction_penalty_it =
reduction_penalty(el_type, ghost_type).begin();
Vector<Real> normal_opening(spatial_dimension);
Vector<Real> tangential_opening(spatial_dimension);
if (! this->model->isExplicit())
this->delta_max(el_type, ghost_type).copy(this->delta_max.previous(el_type, ghost_type));
/// loop on each quadrature point
for (; traction_it != traction_end;
++traction_it, ++opening_it, ++opening_prec_it,
++normal_it, ++sigma_c_it, ++delta_max_it, ++delta_c_it, ++damage_it,
++contact_traction_it, ++insertion_stress_it, ++contact_opening_it,
++delta_max_prev_it, ++reduction_penalty_it) {
Real normal_opening_norm, tangential_opening_norm;
bool penetration;
Real current_penalty = 0.;
this->computeTractionOnQuad(*traction_it,
*delta_max_it,
*delta_max_prev_it,
*delta_c_it,
*insertion_stress_it,
*sigma_c_it,
*opening_it,
*opening_prec_it,
*normal_it,
normal_opening,
tangential_opening,
normal_opening_norm,
tangential_opening_norm,
*damage_it,
penetration,
*reduction_penalty_it,
current_penalty,
*contact_traction_it,
*contact_opening_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::checkDeltaMax(GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// This function set a predefined value to the parameter
/// delta_max_prev of the elements that have been inserted in the
/// last loading step for which convergence has not been
/// reached. This is done before reducing the loading and re-doing
/// the step. Otherwise, the updating of delta_max_prev would be
/// done with reference to the non-convergent solution. In this
/// function also other variables related to the contact and
/// friction behavior are correctly set.
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
ghost_type, _ek_cohesive);
/// the variable "recompute" is set to true to activate the
/// procedure that reduce the penalty parameter for
/// compression. This procedure is set true only during the phase of
/// load_reduction, that has to be set in the maiin file. The
/// penalty parameter will be reduced only for the elements having
/// reduction_penalty = true.
recompute = true;
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if (nb_element == 0) continue;
ElementType el_type = *it;
/// define iterators
Array<Real>::scalar_iterator delta_max_it =
delta_max(el_type, ghost_type).begin();
Array<Real>::scalar_iterator delta_max_end =
delta_max(el_type, ghost_type).end();
Array<Real>::scalar_iterator delta_max_prev_it =
delta_max.previous(el_type, ghost_type).begin();
Array<Real>::scalar_iterator delta_c_it =
delta_c_eff(el_type, ghost_type).begin();
Array<Real>::vector_iterator opening_prec_it =
opening_prec(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_prec_prev_it =
opening_prec.previous(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::scalar_iterator res_sliding_it =
residual_sliding(el_type, ghost_type).begin();
Array<Real>::scalar_iterator res_sliding_prev_it =
residual_sliding.previous(el_type, ghost_type).begin();
/// loop on each quadrature point
for (; delta_max_it != delta_max_end;
++delta_max_it, ++delta_max_prev_it, ++delta_c_it,
++opening_prec_it, ++opening_prec_prev_it,
++res_sliding_it, ++res_sliding_prev_it) {
if (*delta_max_prev_it == 0)
/// elements inserted in the last incremental step, that did
/// not converge
*delta_max_it = *delta_c_it / 1000;
else
/// elements introduced in previous incremental steps, for
/// which a correct value of delta_max_prev already exists
*delta_max_it = *delta_max_prev_it;
/// in case convergence is not reached, set opening_prec to the
/// value referred to the previous incremental step
*opening_prec_it = *opening_prec_prev_it;
/// in case convergence is not reached, set "residual_sliding"
/// for the friction behaviour to the value referred to the
/// previous incremental step
*res_sliding_it = *res_sliding_prev_it;
}
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::resetVariables(GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// This function set the variables "recompute" and
/// "reduction_penalty" to false. It is called by solveStepCohesive
/// when convergence is reached. Such variables, in fact, have to be
/// false at the beginning of a new incremental step.
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
ghost_type, _ek_cohesive);
recompute = false;
// std::cout << "RESET VARIABLE" << std::endl;
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if (nb_element == 0) continue;
ElementType el_type = *it;
Array<bool>::scalar_iterator reduction_penalty_it =
reduction_penalty(el_type, ghost_type).begin();
Array<bool>::scalar_iterator reduction_penalty_end =
reduction_penalty(el_type, ghost_type).end();
/// loop on each quadrature point
for (; reduction_penalty_it != reduction_penalty_end;
++reduction_penalty_it) {
*reduction_penalty_it = false;
}
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
Array<Real>::matrix_iterator tangent_it =
tangent_matrix.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator tangent_end =
tangent_matrix.end(spatial_dimension, spatial_dimension);
Array<Real>::const_vector_iterator normal_it =
normal.begin(spatial_dimension);
Array<Real>::vector_iterator opening_it =
opening(el_type, ghost_type).begin(spatial_dimension);
/// NB: delta_max_it points on delta_max_previous, i.e. the
/// delta_max related to the solution of the previous incremental
/// step
Array<Real>::scalar_iterator delta_max_it =
delta_max.previous(el_type, ghost_type).begin();
Array<Real>::scalar_iterator sigma_c_it =
sigma_c_eff(el_type, ghost_type).begin();
Array<Real>::scalar_iterator delta_c_it =
delta_c_eff(el_type, ghost_type).begin();
Array<Real>::scalar_iterator damage_it =
damage(el_type, ghost_type).begin();
Array<Real>::vector_iterator contact_opening_it =
contact_opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::scalar_iterator res_sliding_prev_it =
residual_sliding.previous(el_type, ghost_type).begin();
Array<bool>::scalar_iterator reduction_penalty_it =
reduction_penalty(el_type, ghost_type).begin();
Vector<Real> normal_opening(spatial_dimension);
Vector<Real> tangential_opening(spatial_dimension);
for (; tangent_it != tangent_end;
++tangent_it, ++normal_it, ++opening_it,
++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
++contact_opening_it, ++reduction_penalty_it) {
Real normal_opening_norm, tangential_opening_norm;
bool penetration;
Real current_penalty = 0.;
this->computeTangentTractionOnQuad(*tangent_it,
*delta_max_it,
*delta_c_it,
*sigma_c_it,
*opening_it,
*normal_it,
normal_opening,
tangential_opening,
normal_opening_norm,
tangential_opening_norm,
*damage_it,
penetration,
*reduction_penalty_it,
current_penalty,
*contact_opening_it);
/// check if the tangential stiffness matrix is symmetric
// for (UInt h = 0; h < spatial_dimension; ++h){
// for (UInt l = h; l < spatial_dimension; ++l){
// if (l > h){
// Real k_ls = (*tangent_it)[spatial_dimension*h+l];
// Real k_us = (*tangent_it)[spatial_dimension*l+h];
// // std::cout << "k_ls = " << k_ls << std::endl;
// // std::cout << "k_us = " << k_us << std::endl;
// if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
// Real error = std::abs((k_ls - k_us) / k_us);
// if (error > 1e-10){
// std::cout << "non symmetric cohesive matrix" << std::endl;
// // std::cout << "error " << error << std::endl;
// }
// }
// }
// }
// }
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialCohesiveLinear);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh
index 34b417771..46be2606e 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh
@@ -1,227 +1,229 @@
/**
* @file material_cohesive_linear.hh
*
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Tue May 08 2012
- * @date last modification: Tue Jul 29 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Jan 14 2016
*
* @brief Linear irreversible cohesive law of mixed mode loading with
* random stress definition for extrinsic type
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__
#define __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
* Cohesive material linear damage for extrinsic case
*
* parameters in the material files :
* - sigma_c : critical stress sigma_c (default: 0)
* - beta : weighting parameter for sliding and normal opening (default: 0)
* - G_cI : fracture energy for mode I (default: 0)
* - G_cII : fracture energy for mode II (default: 0)
* - penalty : stiffness in compression to prevent penetration
*/
template<UInt spatial_dimension>
class MaterialCohesiveLinear : public MaterialCohesive {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialCohesiveLinear(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material parameters
virtual void initMaterial();
/// check stress for cohesive elements' insertion
virtual void checkInsertion(bool check_only = false);
/// compute effective stress norm for insertion check
Real computeEffectiveNorm(const Matrix<Real> & stress,
const Vector<Real> & normal,
const Vector<Real> & tangent,
Vector<Real> & normal_stress) const;
protected:
/// constitutive law
virtual void computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type = _not_ghost);
/// check delta_max for cohesive elements in case of no convergence
/// in the solveStep (only for extrinsic-implicit)
virtual void checkDeltaMax(GhostType ghost_type = _not_ghost);
/// reset variables when convergence is reached (only for
/// extrinsic-implicit)
void resetVariables(GhostType ghost_type = _not_ghost);
/// compute tangent stiffness matrix
virtual void computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type);
/**
* Scale insertion traction sigma_c according to the volume of the
* two elements surrounding a facet
*
* see the article: F. Zhou and J. F. Molinari "Dynamic crack
* propagation with cohesive elements: a methodology to address mesh
* dependency" International Journal for Numerical Methods in
* Engineering (2004)
*/
void scaleInsertionTraction();
/// compute the traction for a given quadrature point
inline void computeTractionOnQuad(Vector<Real> & traction, Real & delta_max,
const Real & delta_max_prev, const Real & delta_c,
const Vector<Real> & insertion_stress, const Real & sigma_c,
Vector<Real> & opening, Vector<Real> & opening_prec, const Vector<Real> & normal,
Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
bool & penetration, bool & reduction_penalty, Real & current_penalty,
Vector<Real> & contact_traction, Vector<Real> & contact_opening);
inline void computeTangentTractionOnQuad(Matrix<Real> & tangent,
Real & delta_max, const Real & delta_c,
const Real & sigma_c,
Vector<Real> & opening, const Vector<Real> & normal,
Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
bool & penetration, bool & reduction_penalty, Real & current_penalty,
Vector<Real> & contact_opening);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get sigma_c_eff
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(InsertionTraction, sigma_c_eff, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// beta parameter
Real beta;
/// beta square inverse to compute effective norm
Real beta2_inv;
/// mode I fracture energy
Real G_c;
/// kappa parameter
Real kappa;
/// constitutive law scalar to compute delta
Real beta2_kappa2;
/// constitutive law scalar to compute traction
Real beta2_kappa;
/// penalty coefficient
Real penalty;
/// reference volume used to scale sigma_c
Real volume_s;
/// weibull exponent used to scale sigma_c
Real m_s;
/// maximum value of the friction coefficient
Real mu_max;
/// penalty parameter for the friction law
Real friction_penalty;
/// variable defining if we are recomputing the last loading step
/// after load_reduction
bool recompute;
/// critical effective stress
RandomInternalField<Real, CohesiveInternalField> sigma_c_eff;
/// effective critical displacement (each element can have a
/// different value)
CohesiveInternalField<Real> delta_c_eff;
/// stress at insertion
CohesiveInternalField<Real> insertion_stress;
/// delta of the previous step
CohesiveInternalField<Real> opening_prec;
/// history parameter for the friction law
CohesiveInternalField<Real> residual_sliding;
/// friction force
CohesiveInternalField<Real> friction_force;
/// variable that defines if the penalty parameter for compression
/// has to be decreased for problems of convergence in the solution
/// loops
CohesiveInternalField<bool> reduction_penalty;
/// variable saying if there should be penalty contact also after
/// breaking the cohesive elements
bool contact_after_breaking;
/// insertion of cohesive element when stress is high enough just on
/// one quadrature point
bool max_quad_stress_insertion;
/// variable saying if friction has to be added to the cohesive behavior
bool friction;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include "material_cohesive_linear_inline_impl.cc"
#endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.cc
index cfa3635c4..d467c7b81 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.cc
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.cc
@@ -1,293 +1,296 @@
/**
* @file material_cohesive_linear_fatigue.cc
+ *
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @date Thu Feb 19 14:40:57 2015
+ *
+ * @date creation: Fri Feb 20 2015
+ * @date last modification: Tue Jan 12 2016
*
* @brief See material_cohesive_linear_fatigue.hh for information
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear_fatigue.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialCohesiveLinearFatigue<spatial_dimension>
::MaterialCohesiveLinearFatigue(SolidMechanicsModel & model,
const ID & id) :
MaterialCohesiveLinear<spatial_dimension>(model, id),
delta_prec("delta_prec", *this),
K_plus("K_plus", *this),
K_minus("K_minus", *this),
T_1d("T_1d", *this),
switches("switches", *this),
delta_dot_prec("delta_dot_prec", *this),
normal_regime("normal_regime", *this) {
this->registerParam("delta_f", delta_f, Real(-1.) ,
_pat_parsable | _pat_readable,
"delta_f");
this->registerParam("progressive_delta_f", progressive_delta_f, false,
_pat_parsable | _pat_readable,
"Whether or not delta_f is equal to delta_max");
this->registerParam("count_switches", count_switches, false,
_pat_parsable | _pat_readable,
"Count the opening/closing switches per element");
this->registerParam("fatigue_ratio", fatigue_ratio, Real(1.),
_pat_parsable | _pat_readable,
"What portion of the cohesive law is subjected to fatigue");
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveLinearFatigue<spatial_dimension>::initMaterial() {
MaterialCohesiveLinear<spatial_dimension>::initMaterial();
// check that delta_f has a proper value or assign a defaul value
if (delta_f < 0) delta_f = this->delta_c_eff;
else if (delta_f < this->delta_c_eff)
AKANTU_DEBUG_ERROR("Delta_f must be greater or equal to delta_c");
delta_prec.initialize(1);
K_plus.initialize(1);
K_minus.initialize(1);
T_1d.initialize(1);
normal_regime.initialize(1);
if (count_switches) {
switches.initialize(1);
delta_dot_prec.initialize(1);
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinearFatigue<spatial_dimension>
::computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
Array<Real>::vector_iterator traction_it =
this->tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_it =
this->opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator contact_traction_it =
this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator contact_opening_it =
this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::const_vector_iterator normal_it = normal.begin(spatial_dimension);
Array<Real>::vector_iterator traction_end =
this->tractions(el_type, ghost_type).end(spatial_dimension);
const Array<Real> & sigma_c_array = this->sigma_c_eff(el_type, ghost_type);
Array<Real> & delta_max_array = this->delta_max(el_type, ghost_type);
const Array<Real> & delta_c_array = this->delta_c_eff(el_type, ghost_type);
Array<Real> & damage_array = this->damage(el_type, ghost_type);
Array<Real>::vector_iterator insertion_stress_it =
this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
Array<Real> & delta_prec_array = delta_prec(el_type, ghost_type);
Array<Real> & K_plus_array = K_plus(el_type, ghost_type);
Array<Real> & K_minus_array = K_minus(el_type, ghost_type);
Array<Real> & T_1d_array = T_1d(el_type, ghost_type);
Array<bool> & normal_regime_array = normal_regime(el_type, ghost_type);
Array<UInt> * switches_array = NULL;
Array<Real> * delta_dot_prec_array = NULL;
if (count_switches) {
switches_array = &switches(el_type, ghost_type);
delta_dot_prec_array = &delta_dot_prec(el_type, ghost_type);
}
Real * memory_space = new Real[2*spatial_dimension];
Vector<Real> normal_opening(memory_space, spatial_dimension);
Vector<Real> tangential_opening(memory_space + spatial_dimension,
spatial_dimension);
Real tolerance = Math::getTolerance();
/// loop on each quadrature point
for (UInt q = 0; traction_it != traction_end;
++traction_it, ++opening_it, ++normal_it,
++contact_traction_it, ++insertion_stress_it, ++contact_opening_it, ++q) {
/// compute normal and tangential opening vectors
Real normal_opening_norm = opening_it->dot(*normal_it);
normal_opening = (*normal_it);
normal_opening *= normal_opening_norm;
tangential_opening = *opening_it;
tangential_opening -= normal_opening;
Real tangential_opening_norm = tangential_opening.norm();
/**
* compute effective opening displacement
* @f$ \delta = \sqrt{
* \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
*/
Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
bool penetration = normal_opening_norm < -tolerance;
if (this->contact_after_breaking == false && Math::are_float_equal(damage_array(q), 1.))
penetration = false;
if (penetration) {
/// use penalty coefficient in case of penetration
*contact_traction_it = normal_opening;
*contact_traction_it *= this->penalty;
*contact_opening_it = normal_opening;
/// don't consider penetration contribution for delta
*opening_it = tangential_opening;
normal_opening.clear();
}
else {
delta += normal_opening_norm * normal_opening_norm;
contact_traction_it->clear();
contact_opening_it->clear();
}
delta = std::sqrt(delta);
/**
* Compute traction @f$ \mathbf{T} = \left(
* \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
* \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
* \frac{\delta}{\delta_c} \right)@f$
*/
// update maximum displacement and damage
delta_max_array(q) = std::max(delta, delta_max_array(q));
damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
Real delta_dot = delta - delta_prec_array(q);
// count switches if asked
if (count_switches) {
if ( (delta_dot > 0. && (*delta_dot_prec_array)(q) <= 0.) ||
(delta_dot < 0. && (*delta_dot_prec_array)(q) >= 0.) )
++((*switches_array)(q));
(*delta_dot_prec_array)(q) = delta_dot;
}
// set delta_f equal to delta_max if desired
if (progressive_delta_f) delta_f = delta_max_array(q);
// broken element case
if (Math::are_float_equal(damage_array(q), 1.))
traction_it->clear();
// just inserted element case
else if (Math::are_float_equal(damage_array(q), 0.)) {
if (penetration)
traction_it->clear();
else
*traction_it = *insertion_stress_it;
// initialize the 1d traction to sigma_c
T_1d_array(q) = sigma_c_array(q);
}
// normal case
else {
// if element is closed then there are zero tractions
if (delta <= tolerance)
traction_it->clear();
// otherwise compute new tractions if the new delta is different
// than the previous one
else if (std::abs(delta_dot) > tolerance) {
// loading case
if (delta_dot > 0.) {
if (!normal_regime_array(q)) {
// equation (4) of the article
K_plus_array(q) *= 1. - delta_dot / delta_f;
// equivalent to equation (2) of the article
T_1d_array(q) += K_plus_array(q) * delta_dot;
// in case of reloading, traction must not exceed that of the
// envelop of the cohesive law
Real max_traction = sigma_c_array(q) * (1 - delta / delta_c_array(q));
bool max_traction_exceeded = T_1d_array(q) > max_traction;
if (max_traction_exceeded) T_1d_array(q) = max_traction;
// switch to standard linear cohesive law
if (delta_max_array(q) > fatigue_ratio * delta_c_array(q)) {
// reset delta_max to avoid big jumps in the traction
delta_max_array(q) = sigma_c_array(q) / (T_1d_array(q) / delta + sigma_c_array(q) / delta_c_array(q));
damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
normal_regime_array(q) = true;
} else {
// equation (3) of the article
K_minus_array(q) = T_1d_array(q) / delta;
// if the traction is following the cohesive envelop, then
// K_plus has to be reset
if (max_traction_exceeded) K_plus_array(q) = K_minus_array(q);
}
} else {
// compute stiffness according to the standard law
K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
}
}
// unloading case
else if (!normal_regime_array(q)) {
// equation (4) of the article
K_plus_array(q) += (K_plus_array(q) - K_minus_array(q)) * delta_dot / delta_f;
// equivalent to equation (2) of the article
T_1d_array(q) = K_minus_array(q) * delta;
}
// applying the actual stiffness
*traction_it = tangential_opening;
*traction_it *= this->beta2_kappa;
*traction_it += normal_opening;
*traction_it *= K_minus_array(q);
}
}
// update precendent delta
delta_prec_array(q) = delta;
}
delete [] memory_space;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialCohesiveLinearFatigue);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.hh
index 1bb26232b..dedda9b19 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.hh
@@ -1,132 +1,136 @@
/**
* @file material_cohesive_linear_fatigue.hh
+ *
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @date Thu Feb 19 14:20:59 2015
*
- * @brief Linear irreversible cohesive law with dissipative
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Jun 25 2015
+ *
+ * @brief Linear irreversible cohesive law with dissipative
* unloading-reloading cycles
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_cohesive_linear.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH__
#define __AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
* Linear irreversible cohesive law with dissipative
* unloading-reloading cycles
*
* This law uses two different stiffnesses during unloading and
* reloading. The implementation is based on the article entitled "A
* cohesive model for fatigue crack growth" by Nguyen, Repetto, Ortiz
* and Radovitzky (2001). This law is identical to the
* MaterialCohesiveLinear one except for the unloading-reloading
* phase.
*
* input parameter:
*
* - delta_f : it must be greater than delta_c and it is inversely
* proportional to the dissipation in the unloading-reloading
* cycles (default: delta_c)
*/
template <UInt spatial_dimension>
class MaterialCohesiveLinearFatigue : public MaterialCohesiveLinear<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialCohesiveLinearFatigue(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material parameters
virtual void initMaterial();
protected:
/// constitutive law
virtual void computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type = _not_ghost);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the switches
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Switches, switches, UInt);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// delta_f parameter
Real delta_f;
/// variable saying if delta_f is equal to delta_max for each
/// element when the traction is computed
bool progressive_delta_f;
/// count the opening/closing switches per element
bool count_switches;
/// delta of the previous step
CohesiveInternalField<Real> delta_prec;
/// stiffness for reloading
CohesiveInternalField<Real> K_plus;
/// stiffness for unloading
CohesiveInternalField<Real> K_minus;
/// 1D traction in the cohesive law
CohesiveInternalField<Real> T_1d;
/// Number of opening/closing switches
CohesiveInternalField<UInt> switches;
/// delta increment of the previous time step
CohesiveInternalField<Real> delta_dot_prec;
/// has the element passed to normal regime (not in fatigue anymore)
CohesiveInternalField<bool> normal_regime;
/// ratio indicating until what point fatigue is applied in the cohesive law
Real fatigue_ratio;
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.cc
index 55ca17900..3b8f27b7b 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.cc
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.cc
@@ -1,382 +1,382 @@
/**
* @file material_cohesive_linear_friction.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date creation: Tue May 08 2012
- * @date last modification: Thu Nov 19 2015
+ * @date creation: Tue Jan 12 2016
+ * @date last modification: Thu Jan 14 2016
*
* @brief Linear irreversible cohesive law of mixed mode loading with
* random stress definition for extrinsic type
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear_friction.hh"
#include "solid_mechanics_model_cohesive.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialCohesiveLinearFriction<spatial_dimension>::MaterialCohesiveLinearFriction(SolidMechanicsModel & model,
const ID & id) :
MaterialParent(model,id),
residual_sliding("residual_sliding", *this),
friction_force("friction_force", *this) {
AKANTU_DEBUG_IN();
this->registerParam("mu", mu_max, Real(0.),
_pat_parsable | _pat_readable,
"Maximum value of the friction coefficient");
this->registerParam("penalty_for_friction", friction_penalty, Real(0.),
_pat_parsable | _pat_readable,
"Penalty parameter for the friction behavior");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinearFriction<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialParent::initMaterial();
friction_force.initialize(spatial_dimension);
residual_sliding.initialize(1);
residual_sliding.initializeHistory();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinearFriction<spatial_dimension>::computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
residual_sliding.resize();
/// define iterators
Array<Real>::vector_iterator traction_it =
this->tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator traction_end =
this->tractions(el_type, ghost_type).end(spatial_dimension);
Array<Real>::vector_iterator opening_it =
this->opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_prev_it =
this->opening.previous(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_prec_it =
this->opening_prec(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator contact_traction_it =
this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator contact_opening_it =
this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::const_iterator< Vector<Real> > normal_it =
this->normal.begin(spatial_dimension);
Array<Real>::iterator<Real>sigma_c_it =
this->sigma_c_eff(el_type, ghost_type).begin();
Array<Real>::iterator<Real>delta_max_it =
this->delta_max(el_type, ghost_type).begin();
Array<Real>::iterator<Real>delta_max_prev_it =
this->delta_max.previous(el_type, ghost_type).begin();
Array<Real>::iterator<Real>delta_c_it =
this->delta_c_eff(el_type, ghost_type).begin();
Array<Real>::iterator<Real>damage_it =
this->damage(el_type, ghost_type).begin();
Array<Real>::vector_iterator insertion_stress_it =
this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::iterator<Real>res_sliding_it =
this->residual_sliding(el_type, ghost_type).begin();
Array<Real>::iterator<Real>res_sliding_prev_it =
this->residual_sliding.previous(el_type, ghost_type).begin();
Array<Real>::vector_iterator friction_force_it =
this->friction_force(el_type, ghost_type).begin(spatial_dimension);
Array<bool>::iterator<bool> reduction_penalty_it =
this->reduction_penalty(el_type, ghost_type).begin();
Vector<Real> normal_opening(spatial_dimension);
Vector<Real> tangential_opening(spatial_dimension);
if (! this->model->isExplicit())
this->delta_max(el_type, ghost_type).copy(this->delta_max.previous(el_type, ghost_type));
/// loop on each quadrature point
for (; traction_it != traction_end;
++traction_it, ++opening_it, ++opening_prev_it, ++opening_prec_it,
++normal_it, ++sigma_c_it,
++delta_max_it, ++delta_c_it, ++damage_it, ++contact_traction_it,
++insertion_stress_it, ++contact_opening_it, ++delta_max_prev_it,
++res_sliding_it, ++res_sliding_prev_it,
++friction_force_it, ++reduction_penalty_it) {
Real normal_opening_norm, tangential_opening_norm;
bool penetration;
Real current_penalty = 0.;
this->computeTractionOnQuad(*traction_it,
*delta_max_it,
*delta_max_prev_it,
*delta_c_it,
*insertion_stress_it,
*sigma_c_it,
*opening_it,
*opening_prec_it,
*normal_it,
normal_opening,
tangential_opening,
normal_opening_norm,
tangential_opening_norm,
*damage_it,
penetration,
*reduction_penalty_it,
current_penalty,
*contact_traction_it,
*contact_opening_it);
if (penetration) {
/* ----------------------------------------- */
Real damage = std::min(*delta_max_prev_it / *delta_c_it, Real(1.));
Real mu = mu_max * std::sqrt(damage);
/// the definition of tau_max refers to the opening
/// (penetration) of the previous incremental step
Real normal_opening_prev_norm = opening_prev_it->dot(*normal_it);
Vector<Real> normal_opening_prev = (*normal_it);
normal_opening_prev *= normal_opening_prev_norm;
Real tau_max = mu * current_penalty * (normal_opening_prev.norm());
Real delta_sliding_norm = std::abs(tangential_opening_norm - *res_sliding_prev_it);
// tau is the norm of the friction force, acting tangentially to the surface
Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
if ((tangential_opening_norm - *res_sliding_it) < -Math::getTolerance())
tau = -tau;
// from tau get the x and y components of friction, to be added in the force vector
Vector<Real> tangent(spatial_dimension);
tangent = tangential_opening / tangential_opening_norm;
*friction_force_it = tau * tangent;
//update residual_sliding
*res_sliding_it = tangential_opening_norm - (tau / friction_penalty);
/* ----------------------------------------- */
} else {
friction_force_it->clear();
}
*traction_it += *friction_force_it;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinearFriction<spatial_dimension>::checkDeltaMax(GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialParent::checkDeltaMax();
Mesh & mesh = this->fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
ghost_type, _ek_cohesive);
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if (nb_element == 0) continue;
ElementType el_type = *it;
/// define iterators
Array<Real>::iterator<Real>delta_max_it =
this->delta_max(el_type, ghost_type).begin();
Array<Real>::iterator<Real>delta_max_end =
this->delta_max(el_type, ghost_type).end();
Array<Real>::iterator<Real>res_sliding_it =
this->residual_sliding(el_type, ghost_type).begin();
Array<Real>::iterator<Real>res_sliding_prev_it =
this->residual_sliding.previous(el_type, ghost_type).begin();
/// loop on each quadrature point
for (; delta_max_it != delta_max_end;
++delta_max_it, ++res_sliding_it, ++res_sliding_prev_it) {
/// in case convergence is not reached, set "residual_sliding"
/// for the friction behaviour to the value referred to the
/// previous incremental step
*res_sliding_it = *res_sliding_prev_it;
}
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinearFriction<spatial_dimension>::computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
Array<Real>::matrix_iterator tangent_it =
tangent_matrix.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator tangent_end =
tangent_matrix.end(spatial_dimension, spatial_dimension);
Array<Real>::const_vector_iterator normal_it =
this->normal.begin(spatial_dimension);
Array<Real>::vector_iterator opening_it =
this->opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_prev_it =
this->opening.previous(el_type, ghost_type).begin(spatial_dimension);
/// NB: delta_max_it points on delta_max_previous, i.e. the
/// delta_max related to the solution of the previous incremental
/// step
Array<Real>::iterator<Real>delta_max_it =
this->delta_max.previous(el_type, ghost_type).begin();
Array<Real>::iterator<Real>sigma_c_it =
this->sigma_c_eff(el_type, ghost_type).begin();
Array<Real>::iterator<Real>delta_c_it =
this->delta_c_eff(el_type, ghost_type).begin();
Array<Real>::iterator<Real>damage_it =
this->damage(el_type, ghost_type).begin();
Array<Real>::iterator< Vector<Real> > contact_opening_it =
this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::iterator<Real>res_sliding_prev_it =
this->residual_sliding.previous(el_type, ghost_type).begin();
Array<bool>::iterator<bool> reduction_penalty_it =
this->reduction_penalty(el_type, ghost_type).begin();
Vector<Real> normal_opening(spatial_dimension);
Vector<Real> tangential_opening(spatial_dimension);
for (; tangent_it != tangent_end;
++tangent_it, ++normal_it, ++opening_it, ++opening_prev_it,
++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
++contact_opening_it, ++res_sliding_prev_it, ++reduction_penalty_it) {
Real normal_opening_norm, tangential_opening_norm;
bool penetration;
Real current_penalty = 0.;
this->computeTangentTractionOnQuad(*tangent_it,
*delta_max_it,
*delta_c_it,
*sigma_c_it,
*opening_it,
*normal_it,
normal_opening,
tangential_opening,
normal_opening_norm,
tangential_opening_norm,
*damage_it,
penetration,
*reduction_penalty_it,
current_penalty,
*contact_opening_it);
if (penetration) {
Real damage = std::min(*delta_max_it / *delta_c_it, Real(1.));
// the friction coefficient mu is increasing with the
// damage. It equals the maximum value when damage = 1.
Real mu = mu_max * damage;
Real normal_opening_prev_norm = opening_prev_it->dot(*normal_it);
Vector<Real> normal_opening_prev = (*normal_it);
normal_opening_prev *= normal_opening_prev_norm;
Real tau_max = mu * current_penalty * normal_opening_prev.norm();
Real delta_sliding_norm = std::abs(tangential_opening_norm - *res_sliding_prev_it);
// tau is the norm of the friction force, acting tangentially to the surface
Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
if (tau < tau_max && tau_max > Math::getTolerance()){
Matrix<Real> I(spatial_dimension, spatial_dimension);
I.eye(1.);
Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
n_outer_n.outerProduct(*normal_it, *normal_it);
Matrix<Real> nn(n_outer_n);
I -= nn;
*tangent_it += I * friction_penalty;
}
}
/// check if the tangential stiffness matrix is symmetric
// for (UInt h = 0; h < spatial_dimension; ++h){
// for (UInt l = h; l < spatial_dimension; ++l){
// if (l > h){
// Real k_ls = (*tangent_it)[spatial_dimension*h+l];
// Real k_us = (*tangent_it)[spatial_dimension*l+h];
// // std::cout << "k_ls = " << k_ls << std::endl;
// // std::cout << "k_us = " << k_us << std::endl;
// if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
// Real error = std::abs((k_ls - k_us) / k_us);
// if (error > 1e-10){
// std::cout << "non symmetric cohesive matrix" << std::endl;
// // std::cout << "error " << error << std::endl;
// }
// }
// }
// }
// }
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialCohesiveLinearFriction);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
index d01b97737..841913221 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
@@ -1,110 +1,112 @@
/**
* @file material_cohesive_linear_friction.hh
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue May 08 2012
- * @date last modification: Tue Jul 29 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Jan 12 2016
*
* @brief Linear irreversible cohesive law of mixed mode loading with
* random stress definition for extrinsic type
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_cohesive_linear.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
#define __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
* Cohesive material linear with friction force
*
* parameters in the material files :
* - mu : friction coefficient
* - penalty_for_friction : Penalty parameter for the friction behavior
*/
template<UInt spatial_dimension>
class MaterialCohesiveLinearFriction : public MaterialCohesiveLinear<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
typedef MaterialCohesiveLinear<spatial_dimension> MaterialParent;
public:
MaterialCohesiveLinearFriction(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material parameters
virtual void initMaterial();
protected:
/// constitutive law
virtual void computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type = _not_ghost);
/// check delta_max for cohesive elements in case of no convergence
/// in the solveStep (only for extrinsic-implicit)
virtual void checkDeltaMax(GhostType ghost_type = _not_ghost);
/// compute tangent stiffness matrix
virtual void computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// maximum value of the friction coefficient
Real mu_max;
/// penalty parameter for the friction law
Real friction_penalty;
/// history parameter for the friction law
CohesiveInternalField<Real> residual_sliding;
/// friction force
CohesiveInternalField<Real> friction_force;
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc
index 2aba0b544..8d8983420 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc
@@ -1,313 +1,317 @@
/**
* @file material_cohesive_linear_inline_impl.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @date Tue Apr 21 14:49:56 2015
+ *
+ * @date creation: Wed Apr 22 2015
+ * @date last modification: Thu Jan 14 2016
*
* @brief Inline functions of the MaterialCohesiveLinear
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
#define __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline Real MaterialCohesiveLinear<dim>::computeEffectiveNorm(const Matrix<Real> & stress,
const Vector<Real> & normal,
const Vector<Real> & tangent,
Vector<Real> & normal_traction) const {
normal_traction.mul<false>(stress, normal);
Real normal_contrib = normal_traction.dot(normal);
/// in 3D tangential components must be summed
Real tangent_contrib = 0;
if (dim == 2) {
Real tangent_contrib_tmp = normal_traction.dot(tangent);
tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
}
else if (dim == 3) {
for (UInt s = 0; s < dim - 1; ++s) {
const Vector<Real> tangent_v(tangent.storage() + s * dim, dim);
Real tangent_contrib_tmp = normal_traction.dot(tangent_v);
tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
}
}
tangent_contrib = std::sqrt(tangent_contrib);
normal_contrib = std::max(Real(0.), normal_contrib);
return std::sqrt(normal_contrib * normal_contrib + tangent_contrib * tangent_contrib * beta2_inv);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialCohesiveLinear<dim>::computeTractionOnQuad(
Vector<Real> & traction,
Real & delta_max,
const Real & delta_max_prev,
const Real & delta_c,
const Vector<Real> & insertion_stress,
const Real & sigma_c,
Vector<Real> & opening,
Vector<Real> & opening_prec,
const Vector<Real> & normal,
Vector<Real> & normal_opening,
Vector<Real> & tangential_opening,
Real & normal_opening_norm,
Real & tangential_opening_norm,
Real & damage,
bool & penetration,
bool & reduction_penalty,
Real & current_penalty,
Vector<Real> & contact_traction,
Vector<Real> & contact_opening) {
/// compute normal and tangential opening vectors
normal_opening_norm = opening.dot(normal);
normal_opening = normal;
normal_opening *= normal_opening_norm;
tangential_opening = opening;
tangential_opening -= normal_opening;
tangential_opening_norm = tangential_opening.norm();
/**
* compute effective opening displacement
* @f$ \delta = \sqrt{
* \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
*/
Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
penetration = normal_opening_norm < -Math::getTolerance();
if (this->contact_after_breaking == false && Math::are_float_equal(damage, 1.))
penetration = false;
/**
* if during the convergence loop a cohesive element continues to
* jumps from penetration to opening, and convergence is not
* reached, its penalty parameter will be reduced in the
* recomputation of the same incremental step. recompute is set
* equal to true when convergence is not reached in the
* solveStepCohesive function and the execution of the program
* goes back to the main file where the variable load_reduction
* is set equal to true.
*/
// opening_prec is the opening of the previous convergence loop
// (NB: it is different from opening_prev, that refers to the solution
// of the previous incremental step)
Real normal_opening_prec_norm = opening_prec.dot(normal);
opening_prec = opening;
if (!this->model->isExplicit() && !this->recompute)
if ((normal_opening_prec_norm * normal_opening_norm) < 0) {
reduction_penalty = true;
}
if (penetration) {
if (this->recompute && reduction_penalty){
/// the penalty parameter is locally reduced
current_penalty = this->penalty / 1000.;
}
else
current_penalty = this->penalty;
/// use penalty coefficient in case of penetration
contact_traction = normal_opening;
contact_traction *= current_penalty;
contact_opening = normal_opening;
/// don't consider penetration contribution for delta
opening = tangential_opening;
normal_opening.clear();
}
else {
delta += normal_opening_norm * normal_opening_norm;
contact_traction.clear();
contact_opening.clear();
}
delta = std::sqrt(delta);
/// update maximum displacement and damage
delta_max = std::max(delta_max, delta);
damage = std::min(delta_max / delta_c, Real(1.));
/**
* Compute traction @f$ \mathbf{T} = \left(
* \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
* \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
* \frac{\delta}{\delta_c} \right)@f$
*/
if (Math::are_float_equal(damage, 1.))
traction.clear();
else if (Math::are_float_equal(damage, 0.)) {
if (penetration)
traction.clear();
else
traction = insertion_stress;
}
else {
traction = tangential_opening;
traction *= beta2_kappa;
traction += normal_opening;
AKANTU_DEBUG_ASSERT(delta_max != 0.,
"Division by zero, tolerance might be too low");
traction *= sigma_c / delta_max * (1. - damage);
}
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialCohesiveLinear<dim>::computeTangentTractionOnQuad(
Matrix<Real> & tangent,
Real & delta_max,
const Real & delta_c,
const Real & sigma_c,
Vector<Real> & opening,
const Vector<Real> & normal,
Vector<Real> & normal_opening,
Vector<Real> & tangential_opening,
Real & normal_opening_norm,
Real & tangential_opening_norm,
Real & damage,
bool & penetration,
bool & reduction_penalty,
Real & current_penalty,
Vector<Real> & contact_opening) {
/// During the update of the residual the interpenetrations are
/// stored in the array "contact_opening", therefore, in the case
/// of penetration, in the array "opening" there are only the
/// tangential components.
opening += contact_opening;
/// compute normal and tangential opening vectors
normal_opening_norm = opening.dot(normal);
normal_opening = normal;
normal_opening *= normal_opening_norm;
tangential_opening = opening;
tangential_opening -= normal_opening;
tangential_opening_norm = tangential_opening.norm();
penetration = normal_opening_norm < -Math::getTolerance();
if (contact_after_breaking == false && Math::are_float_equal(damage, 1.))
penetration = false;
Real derivative = 0; // derivative = d(t/delta)/ddelta
Real t = 0;
Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
n_outer_n.outerProduct(normal, normal);
if (penetration){
if (recompute && reduction_penalty)
current_penalty = this->penalty / 1000.;
else
current_penalty = this->penalty;
/// stiffness in compression given by the penalty parameter
tangent += n_outer_n;
tangent *= current_penalty;
opening = tangential_opening;
normal_opening_norm = opening.dot(normal);
normal_opening = normal;
normal_opening *= normal_opening_norm;
}
else{
delta += normal_opening_norm * normal_opening_norm;
}
delta = std::sqrt(delta);
/// Delta has to be different from 0 to have finite values of
/// tangential stiffness. At the element insertion, delta =
/// 0. Therefore, a fictictious value is defined, for the
/// evaluation of the first value of K.
if (delta < Math::getTolerance())
delta = (delta_c)/1000.;
if (delta >= delta_max){
if (delta <= delta_c){
derivative = -sigma_c / (delta * delta);
t = sigma_c * (1 - delta / delta_c);
} else {
derivative = 0.;
t = 0.;
}
} else if (delta < delta_max){
Real tmax = sigma_c * (1 - delta_max / delta_c);
t = tmax / delta_max * delta;
}
/// computation of the derivative of the constitutive law (dT/ddelta)
Matrix<Real> I(spatial_dimension, spatial_dimension);
I.eye(this->beta2_kappa);
Matrix<Real> nn(n_outer_n);
nn *= (1. - this->beta2_kappa);
nn += I;
nn *= t/delta;
Vector<Real> t_tilde(normal_opening);
t_tilde *= (1. - this->beta2_kappa2);
Vector<Real> mm(opening);
mm *= this->beta2_kappa2;
t_tilde += mm;
Vector<Real> t_hat(normal_opening);
t_hat += this->beta2_kappa * tangential_opening;
Matrix<Real> prov(spatial_dimension, spatial_dimension);
prov.outerProduct(t_hat, t_tilde);
prov *= derivative/delta;
prov += nn;
Matrix<Real> prov_t = prov.transpose();
tangent += prov_t;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
/* -------------------------------------------------------------------------- */
#endif //__AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc
index 140d1f284..a56f19514 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc
+++ b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc
@@ -1,624 +1,625 @@
/**
* @file material_cohesive.cc
*
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Feb 22 2012
- * @date last modification: Tue Jul 29 2014
+ * @date last modification: Tue Jan 12 2016
*
* @brief Specialization of the material class for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_cohesive.hh"
#include "solid_mechanics_model_cohesive.hh"
#include "sparse_matrix.hh"
#include "dof_synchronizer.hh"
#include "aka_random_generator.hh"
#include "shape_cohesive.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
MaterialCohesive::MaterialCohesive(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
facet_filter("facet_filter", id, this->getMemoryID()),
fem_cohesive(&(model.getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine"))),
reversible_energy("reversible_energy", *this),
total_energy("total_energy", *this),
opening("opening", *this),
opening_old("opening (old)", *this),
tractions("tractions", *this),
tractions_old("tractions (old)", *this),
contact_tractions("contact_tractions", *this),
contact_opening("contact_opening", *this),
delta_max("delta max", *this),
use_previous_delta_max(false),
use_previous_opening(false),
damage("damage", *this),
sigma_c("sigma_c", *this),
normal(0, spatial_dimension, "normal") {
AKANTU_DEBUG_IN();
this->model = dynamic_cast<SolidMechanicsModelCohesive*>(&model);
this->registerParam("sigma_c", sigma_c,
_pat_parsable | _pat_readable, "Critical stress");
this->registerParam("delta_c", delta_c, Real(0.),
_pat_parsable | _pat_readable, "Critical displacement");
this->model->getMesh().initElementTypeMapArray(this->element_filter,
1,
spatial_dimension,
false,
_ek_cohesive);
if (this->model->getIsExtrinsic())
this->model->getMeshFacets().initElementTypeMapArray(facet_filter, 1,
spatial_dimension - 1);
this->reversible_energy.initialize(1 );
this->total_energy .initialize(1 );
this->tractions_old .initialize(spatial_dimension);
this->tractions .initialize(spatial_dimension);
this->opening_old .initialize(spatial_dimension);
this->contact_tractions.initialize(spatial_dimension);
this->contact_opening .initialize(spatial_dimension);
this->opening .initialize(spatial_dimension);
this->delta_max .initialize(1 );
this->damage .initialize(1 );
if (this->model->getIsExtrinsic()) this->sigma_c.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
MaterialCohesive::~MaterialCohesive() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
if (this->use_previous_delta_max) this->delta_max.initializeHistory();
if (this->use_previous_opening) this->opening.initializeHistory();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::assembleResidual(GhostType ghost_type) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_DEBUG_TOOLS)
debug::element_manager.printData(debug::_dm_material_cohesive,
"Cohesive Tractions",
tractions);
#endif
Array<Real> & residual = const_cast<Array<Real> &>(model->getResidual());
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
ghost_type, _ek_cohesive);
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if (nb_element == 0) continue;
const Array<Real> & shapes = fem_cohesive->getShapes(*it, ghost_type);
Array<Real> & traction = tractions(*it, ghost_type);
Array<Real> & contact_traction = contact_tractions(*it, ghost_type);
UInt size_of_shapes = shapes.getNbComponent();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
UInt nb_quadrature_points = fem_cohesive->getNbIntegrationPoints(*it, ghost_type);
/// compute @f$t_i N_a@f$
Array<Real> * traction_cpy = new Array<Real>(nb_element * nb_quadrature_points,
spatial_dimension * size_of_shapes);
Array<Real>::iterator<Matrix<Real> > traction_it
= traction.begin(spatial_dimension, 1);
Array<Real>::iterator<Matrix<Real> > contact_traction_it
= contact_traction.begin(spatial_dimension, 1);
Array<Real>::const_iterator<Matrix<Real> > shapes_filtered_begin
= shapes.begin(1, size_of_shapes);
Array<Real>::iterator<Matrix<Real> > traction_cpy_it
= traction_cpy->begin(spatial_dimension, size_of_shapes);
Matrix<Real> traction_tmp(spatial_dimension, 1);
for (UInt el = 0; el < nb_element; ++el) {
UInt current_quad = elem_filter(el) * nb_quadrature_points;
for (UInt q = 0; q < nb_quadrature_points; ++q, ++traction_it,
++contact_traction_it, ++current_quad, ++traction_cpy_it) {
const Matrix<Real> & shapes_filtered = shapes_filtered_begin[current_quad];
traction_tmp.copy(*traction_it);
traction_tmp += *contact_traction_it;
traction_cpy_it->mul<false, false>(traction_tmp, shapes_filtered);
}
}
/**
* compute @f$\int t \cdot N\, dS@f$ by @f$ \sum_q \mathbf{N}^t
* \mathbf{t}_q \overline w_q J_q@f$
*/
Array<Real> * int_t_N = new Array<Real>(nb_element,
spatial_dimension*size_of_shapes,
"int_t_N");
fem_cohesive->integrate(*traction_cpy, *int_t_N,
spatial_dimension * size_of_shapes,
*it, ghost_type,
elem_filter);
delete traction_cpy;
int_t_N->extendComponentsInterlaced(2, int_t_N->getNbComponent());
Real * int_t_N_val = int_t_N->storage();
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < size_of_shapes * spatial_dimension; ++n)
int_t_N_val[n] *= -1.;
int_t_N_val += nb_nodes_per_element * spatial_dimension;
}
/// assemble
model->getFEEngineBoundary().assembleArray(*int_t_N, residual,
model->getDOFSynchronizer().getLocalDOFEquationNumbers(),
residual.getNbComponent(),
*it, ghost_type, elem_filter, 1);
delete int_t_N;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::assembleStiffnessMatrix(GhostType ghost_type) {
AKANTU_DEBUG_IN();
SparseMatrix & K = const_cast<SparseMatrix &>(model->getStiffnessMatrix());
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
ghost_type, _ek_cohesive);
for(; it != last_type; ++it) {
UInt nb_quadrature_points = fem_cohesive->getNbIntegrationPoints(*it, ghost_type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
const Array<Real> & shapes = fem_cohesive->getShapes(*it, ghost_type);
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if(!nb_element) continue;
UInt size_of_shapes = shapes.getNbComponent();
Array<Real> * shapes_filtered =
new Array<Real>(nb_element*nb_quadrature_points,
size_of_shapes, "filtered shapes");
Real * shapes_val = shapes.storage();
Real * shapes_filtered_val = shapes_filtered->storage();
UInt * elem_filter_val = elem_filter.storage();
for (UInt el = 0; el < nb_element; ++el) {
shapes_val = shapes.storage() + elem_filter_val[el] *
size_of_shapes * nb_quadrature_points;
memcpy(shapes_filtered_val, shapes_val,
size_of_shapes * nb_quadrature_points * sizeof(Real));
shapes_filtered_val += size_of_shapes * nb_quadrature_points;
}
/**
* compute A matrix @f$ \mathbf{A} = \left[\begin{array}{c c c c c c c c c c c c}
* 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 \\
* 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 \\
* 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 \\
* 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 \\
* 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 \\
* 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1
* \end{array} \right]@f$
**/
// UInt size_of_A = spatial_dimension*size_of_shapes*spatial_dimension*nb_nodes_per_element;
// Real * A = new Real[size_of_A];
// memset(A, 0, size_of_A*sizeof(Real));
Matrix<Real> A(spatial_dimension*size_of_shapes,
spatial_dimension*nb_nodes_per_element);
for ( UInt i = 0; i < spatial_dimension*size_of_shapes; ++i) {
A(i, i) = 1;
A(i, i + spatial_dimension*size_of_shapes) = -1;
}
/// compute traction. This call is not necessary for the linear
/// cohesive law that, currently, is the only one used for the
/// extrinsic approach.
if (!model->getIsExtrinsic()){
computeTraction(ghost_type);
}
/// get the tangent matrix @f$\frac{\partial{(t/\delta)}}{\partial{\delta}} @f$
Array<Real> * tangent_stiffness_matrix =
new Array<Real>(nb_element * nb_quadrature_points,
spatial_dimension * spatial_dimension,
"tangent_stiffness_matrix");
// Array<Real> * normal = new Array<Real>(nb_element * nb_quadrature_points, spatial_dimension, "normal");
normal.resize(nb_quadrature_points);
computeNormal(model->getCurrentPosition(), normal, *it, ghost_type);
/// compute openings @f$\mathbf{\delta}@f$
//computeOpening(model->getDisplacement(), opening(*it, ghost_type), *it, ghost_type);
tangent_stiffness_matrix->clear();
computeTangentTraction(*it, *tangent_stiffness_matrix, normal, ghost_type);
// delete normal;
UInt size_at_nt_d_n_a = spatial_dimension*nb_nodes_per_element*spatial_dimension*nb_nodes_per_element;
Array<Real> * at_nt_d_n_a = new Array<Real> (nb_element*nb_quadrature_points,
size_at_nt_d_n_a,
"A^t*N^t*D*N*A");
Array<Real>::iterator<Vector<Real> > shapes_filt_it =
shapes_filtered->begin(size_of_shapes);
Array<Real>::matrix_iterator D_it =
tangent_stiffness_matrix->begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator At_Nt_D_N_A_it =
at_nt_d_n_a->begin(spatial_dimension * nb_nodes_per_element,
spatial_dimension * nb_nodes_per_element);
Array<Real>::matrix_iterator At_Nt_D_N_A_end =
at_nt_d_n_a->end(spatial_dimension * nb_nodes_per_element,
spatial_dimension * nb_nodes_per_element);
Matrix<Real> N (spatial_dimension, spatial_dimension * size_of_shapes);
Matrix<Real> N_A (spatial_dimension, spatial_dimension * nb_nodes_per_element);
Matrix<Real> D_N_A(spatial_dimension, spatial_dimension * nb_nodes_per_element);
for(; At_Nt_D_N_A_it != At_Nt_D_N_A_end; ++At_Nt_D_N_A_it, ++D_it, ++shapes_filt_it) {
N.clear();
/**
* store the shapes in voigt notations matrix @f$\mathbf{N} =
* \begin{array}{cccccc} N_0(\xi) & 0 & N_1(\xi) &0 & N_2(\xi) & 0 \\
* 0 & * N_0(\xi)& 0 &N_1(\xi)& 0 & N_2(\xi) \end{array} @f$
**/
for (UInt i = 0; i < spatial_dimension ; ++i)
for (UInt n = 0; n < size_of_shapes; ++n)
N(i, i + spatial_dimension * n) = (*shapes_filt_it)(n);
/**
* compute stiffness matrix @f$ \mathbf{K} = \delta \mathbf{U}^T
* \int_{\Gamma_c} {\mathbf{P}^t \frac{\partial{\mathbf{t}}} {\partial{\delta}}
* \mathbf{P} d\Gamma \Delta \mathbf{U}} @f$
**/
N_A.mul<false, false>(N, A);
D_N_A.mul<false, false>(*D_it, N_A);
(*At_Nt_D_N_A_it).mul<true, false>(D_N_A, N_A);
}
delete tangent_stiffness_matrix;
delete shapes_filtered;
Array<Real> * K_e = new Array<Real>(nb_element, size_at_nt_d_n_a,
"K_e");
fem_cohesive->integrate(*at_nt_d_n_a, *K_e,
size_at_nt_d_n_a,
*it, ghost_type,
elem_filter);
delete at_nt_d_n_a;
model->getFEEngine().assembleMatrix(*K_e, K, spatial_dimension,
*it, ghost_type, elem_filter);
delete K_e;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- *
* Compute traction from displacements
*
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void MaterialCohesive::computeTraction(GhostType ghost_type) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_DEBUG_TOOLS)
debug::element_manager.printData(debug::_dm_material_cohesive,
"Cohesive Openings",
opening);
#endif
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
ghost_type, _ek_cohesive);
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if (nb_element == 0) continue;
UInt nb_quadrature_points =
nb_element*fem_cohesive->getNbIntegrationPoints(*it, ghost_type);
normal.resize(nb_quadrature_points);
/// compute normals @f$\mathbf{n}@f$
computeNormal(model->getCurrentPosition(), normal, *it, ghost_type);
/// compute openings @f$\mathbf{\delta}@f$
computeOpening(model->getDisplacement(), opening(*it, ghost_type), *it, ghost_type);
/// compute traction @f$\mathbf{t}@f$
computeTraction(normal, *it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::computeNormal(const Array<Real> & position,
Array<Real> & normal,
ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
if (type == _cohesive_1d_2)
fem_cohesive->computeNormalsOnIntegrationPoints(position,
normal,
type, ghost_type);
else {
#define COMPUTE_NORMAL(type) \
fem_cohesive->getShapeFunctions(). \
computeNormalsOnIntegrationPoints<type, CohesiveReduceFunctionMean>(position, \
normal, \
ghost_type, \
element_filter(type, ghost_type));
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_NORMAL);
#undef COMPUTE_NORMAL
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::computeOpening(const Array<Real> & displacement,
Array<Real> & opening,
ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
#define COMPUTE_OPENING(type) \
fem_cohesive->getShapeFunctions(). \
interpolateOnIntegrationPoints<type, CohesiveReduceFunctionOpening>(displacement, \
opening, \
spatial_dimension, \
ghost_type, \
element_filter(type, ghost_type));
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_OPENING);
#undef COMPUTE_OPENING
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::computeEnergies() {
AKANTU_DEBUG_IN();
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it =
mesh.firstType(spatial_dimension, _not_ghost, _ek_cohesive);
Mesh::type_iterator last_type =
mesh.lastType(spatial_dimension, _not_ghost, _ek_cohesive);
Real * memory_space = new Real[2*spatial_dimension];
Vector<Real> b(memory_space, spatial_dimension);
Vector<Real> h(memory_space + spatial_dimension, spatial_dimension);
for(; it != last_type; ++it) {
Array<Real>::iterator<Real> erev =
reversible_energy(*it, _not_ghost).begin();
Array<Real>::iterator<Real> etot =
total_energy(*it, _not_ghost).begin();
Array<Real>::vector_iterator traction_it =
tractions(*it, _not_ghost).begin(spatial_dimension);
Array<Real>::vector_iterator traction_old_it =
tractions_old(*it, _not_ghost).begin(spatial_dimension);
Array<Real>::vector_iterator opening_it =
opening(*it, _not_ghost).begin(spatial_dimension);
Array<Real>::vector_iterator opening_old_it =
opening_old(*it, _not_ghost).begin(spatial_dimension);
Array<Real>::vector_iterator traction_end =
tractions(*it, _not_ghost).end(spatial_dimension);
/// loop on each quadrature point
for (; traction_it != traction_end;
++traction_it, ++traction_old_it,
++opening_it, ++opening_old_it,
++erev, ++etot) {
/// trapezoidal integration
b = *opening_it;
b -= *opening_old_it;
h = *traction_old_it;
h += *traction_it;
*etot += .5 * b.dot(h);
*erev = .5 * traction_it->dot(*opening_it);
}
}
delete [] memory_space;
/// update old values
it = mesh.firstType(spatial_dimension, _not_ghost, _ek_cohesive);
GhostType ghost_type = _not_ghost;
for(; it != last_type; ++it) {
tractions_old(*it, ghost_type).copy(tractions(*it, ghost_type));
opening_old(*it, ghost_type).copy(opening(*it, ghost_type));
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real MaterialCohesive::getReversibleEnergy() {
AKANTU_DEBUG_IN();
Real erev = 0.;
/// integrate reversible energy for each type of elements
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
_not_ghost, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
_not_ghost, _ek_cohesive);
for(; it != last_type; ++it) {
erev += fem_cohesive->integrate(reversible_energy(*it, _not_ghost), *it,
_not_ghost, element_filter(*it, _not_ghost));
}
AKANTU_DEBUG_OUT();
return erev;
}
/* -------------------------------------------------------------------------- */
Real MaterialCohesive::getDissipatedEnergy() {
AKANTU_DEBUG_IN();
Real edis = 0.;
/// integrate dissipated energy for each type of elements
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
_not_ghost, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
_not_ghost, _ek_cohesive);
for(; it != last_type; ++it) {
Array<Real> dissipated_energy(total_energy(*it, _not_ghost));
dissipated_energy -= reversible_energy(*it, _not_ghost);
edis += fem_cohesive->integrate(dissipated_energy, *it,
_not_ghost, element_filter(*it, _not_ghost));
}
AKANTU_DEBUG_OUT();
return edis;
}
/* -------------------------------------------------------------------------- */
Real MaterialCohesive::getContactEnergy() {
AKANTU_DEBUG_IN();
Real econ = 0.;
/// integrate contact energy for each type of elements
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
_not_ghost, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
_not_ghost, _ek_cohesive);
for(; it != last_type; ++it) {
Array<UInt> & el_filter = element_filter(*it, _not_ghost);
UInt nb_quad_per_el = fem_cohesive->getNbIntegrationPoints(*it, _not_ghost);
UInt nb_quad_points = el_filter.getSize() * nb_quad_per_el;
Array<Real> contact_energy(nb_quad_points);
Array<Real>::vector_iterator contact_traction_it =
contact_tractions(*it, _not_ghost).begin(spatial_dimension);
Array<Real>::vector_iterator contact_opening_it =
contact_opening(*it, _not_ghost).begin(spatial_dimension);
/// loop on each quadrature point
for (UInt el = 0; el < nb_quad_points;
++contact_traction_it, ++contact_opening_it, ++el) {
contact_energy(el) = .5 * contact_traction_it->dot(*contact_opening_it);
}
econ += fem_cohesive->integrate(contact_energy, *it,
_not_ghost, el_filter);
}
AKANTU_DEBUG_OUT();
return econ;
}
/* -------------------------------------------------------------------------- */
Real MaterialCohesive::getEnergy(std::string type) {
AKANTU_DEBUG_IN();
if (type == "reversible") return getReversibleEnergy();
else if (type == "dissipated") return getDissipatedEnergy();
else if (type == "cohesive contact") return getContactEnergy();
AKANTU_DEBUG_OUT();
return 0.;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
index 0eade6996..979b20f86 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
@@ -1,267 +1,268 @@
/**
* @file material_cohesive.hh
*
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Feb 22 2012
- * @date last modification: Tue Jul 29 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Jan 12 2016
*
* @brief Specialization of the material class for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material.hh"
#include "fe_engine_template.hh"
#include "aka_common.hh"
#include "cohesive_internal_field.hh"
#include "cohesive_element_inserter.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_HH__
#define __AKANTU_MATERIAL_COHESIVE_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class SolidMechanicsModelCohesive;
}
__BEGIN_AKANTU__
class MaterialCohesive : public Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef FEEngineTemplate<IntegratorGauss,
ShapeLagrange, _ek_cohesive> MyFEEngineCohesiveType;
public:
MaterialCohesive(SolidMechanicsModel& model, const ID & id = "");
virtual ~MaterialCohesive();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material computed parameter
virtual void initMaterial();
/// compute tractions (including normals and openings)
void computeTraction(GhostType ghost_type = _not_ghost);
/// assemble residual
void assembleResidual(GhostType ghost_type = _not_ghost);
/// compute reversible and total energies by element
void computeEnergies();
/// check stress for cohesive elements' insertion, by default it
/// also updates the cohesive elements' data
virtual void checkInsertion(bool check_only = false) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// check delta_max for cohesive elements in case of no convergence
/// in the solveStep (only for extrinsic-implicit)
virtual void checkDeltaMax(GhostType ghost_type = _not_ghost) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// reset variables when convergence is reached (only for
/// extrinsic-implicit)
virtual void resetVariables(GhostType ghost_type = _not_ghost) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// interpolate stress on given positions for each element (empty
/// implemantation to avoid the generic call to be done on cohesive elements)
virtual void interpolateStress(__attribute__((unused)) const ElementType type,
__attribute__((unused)) Array<Real> & result) { };
/// compute the stresses
virtual void computeAllStresses(__attribute__((unused)) GhostType ghost_type = _not_ghost) { };
// add the facet to be handled by the material
UInt addFacet(const Element & element);
protected:
virtual void computeTangentTraction(__attribute__((unused)) const ElementType & el_type,
__attribute__((unused)) Array<Real> & tangent_matrix,
__attribute__((unused)) const Array<Real> & normal,
__attribute__((unused)) GhostType ghost_type = _not_ghost) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// compute the normal
void computeNormal(const Array<Real> & position,
Array<Real> & normal,
ElementType type,
GhostType ghost_type);
/// compute the opening
void computeOpening(const Array<Real> & displacement,
Array<Real> & normal,
ElementType type,
GhostType ghost_type);
template<ElementType type>
void computeNormal(const Array<Real> & position,
Array<Real> & normal,
GhostType ghost_type);
/// assemble stiffness
void assembleStiffnessMatrix(GhostType ghost_type);
/// constitutive law
virtual void computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type = _not_ghost) = 0;
/// parallelism functions
inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the opening
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Opening, opening, Real);
/// get the traction
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Traction, tractions, Real);
/// get damage
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real);
/// get facet filter
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetFilter, facet_filter, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetFilter, facet_filter, UInt);
AKANTU_GET_MACRO(FacetFilter, facet_filter, const ElementTypeMapArray<UInt> &);
// AKANTU_GET_MACRO(ElementFilter, element_filter, const ElementTypeMapArray<UInt> &);
/// compute reversible energy
Real getReversibleEnergy();
/// compute dissipated energy
Real getDissipatedEnergy();
/// compute contact energy
Real getContactEnergy();
/// get energy
virtual Real getEnergy(std::string type);
/// return the energy (identified by id) for the provided element
virtual Real getEnergy(std::string energy_id, ElementType type, UInt index) {
return Material::getEnergy(energy_id, type, index);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// list of facets assigned to this material
ElementTypeMapArray<UInt> facet_filter;
/// Link to the cohesive fem object in the model
MyFEEngineCohesiveType * fem_cohesive;
private:
/// reversible energy by quadrature point
CohesiveInternalField<Real> reversible_energy;
/// total energy by quadrature point
CohesiveInternalField<Real> total_energy;
protected:
/// opening in all elements and quadrature points
CohesiveInternalField<Real> opening;
/// opening in all elements and quadrature points (previous time step)
CohesiveInternalField<Real> opening_old;
/// traction in all elements and quadrature points
CohesiveInternalField<Real> tractions;
/// traction in all elements and quadrature points (previous time step)
CohesiveInternalField<Real> tractions_old;
/// traction due to contact
CohesiveInternalField<Real> contact_tractions;
/// normal openings for contact tractions
CohesiveInternalField<Real> contact_opening;
/// maximum displacement
CohesiveInternalField<Real> delta_max;
/// tell if the previous delta_max state is needed (in iterative schemes)
bool use_previous_delta_max;
/// tell if the previous opening state is needed (in iterative schemes)
bool use_previous_opening;
/// damage
CohesiveInternalField<Real> damage;
/// pointer to the solid mechanics model for cohesive elements
SolidMechanicsModelCohesive * model;
/// critical stress
RandomInternalField<Real, FacetInternalField> sigma_c;
/// critical displacement
Real delta_c;
/// array to temporarily store the normals
Array<Real> normal;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_cohesive_inline_impl.cc"
__END_AKANTU__
#include "cohesive_internal_field_tmpl.hh"
#endif /* __AKANTU_MATERIAL_COHESIVE_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc
index 5c62b3eae..38206e23e 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc
@@ -1,94 +1,95 @@
/**
* @file material_cohesive_inline_impl.cc
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Thu Feb 23 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief MaterialCohesive inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline UInt MaterialCohesive::addFacet(const Element & element) {
Array<UInt> & f_filter = facet_filter(element.type, element.ghost_type);
f_filter.push_back(element.element);
return f_filter.getSize()-1;
}
/* -------------------------------------------------------------------------- */
template<ElementType type>
void MaterialCohesive::computeNormal(const Array<Real> & position,
Array<Real> & normal,
GhostType ghost_type) {
}
/* -------------------------------------------------------------------------- */
inline UInt MaterialCohesive::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
switch (tag) {
case _gst_smm_stress: {
return 2 * spatial_dimension * sizeof(Real) * this->getModel().getNbIntegrationPoints(elements, "CohesiveFEEngine");
}
case _gst_smmc_damage: {
return sizeof(Real) * this->getModel().getNbIntegrationPoints(elements, "CohesiveFEEngine");
}
default: {}
}
return 0;
}
/* -------------------------------------------------------------------------- */
inline void MaterialCohesive::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
switch (tag) {
case _gst_smm_stress: {
packElementDataHelper(tractions, buffer, elements, "CohesiveFEEngine");
packElementDataHelper(contact_tractions, buffer, elements, "CohesiveFEEngine");
break;
}
case _gst_smmc_damage:
packElementDataHelper(damage, buffer, elements, "CohesiveFEEngine"); break;
default: {}
}
}
/* -------------------------------------------------------------------------- */
inline void MaterialCohesive::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
switch (tag) {
case _gst_smm_stress: {
unpackElementDataHelper(tractions, buffer, elements, "CohesiveFEEngine");
unpackElementDataHelper(contact_tractions, buffer, elements, "CohesiveFEEngine");
break;
}
case _gst_smmc_damage:
unpackElementDataHelper(damage, buffer, elements, "CohesiveFEEngine"); break;
default: {}
}
}
diff --git a/src/model/solid_mechanics/materials/material_cohesive_includes.hh b/src/model/solid_mechanics/materials/material_cohesive_includes.hh
index 70ede7cf9..00bfb1433 100644
--- a/src/model/solid_mechanics/materials/material_cohesive_includes.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive_includes.hh
@@ -1,46 +1,47 @@
/**
* @file material_cohesive_includes.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Oct 31 2012
- * @date last modification: Fri Mar 21 2014
+ * @date creation: Sun Sep 26 2010
+ * @date last modification: Tue Jan 12 2016
*
* @brief List of includes for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_CMAKE_LIST_MATERIALS
#include "material_cohesive.hh"
#include "material_cohesive_linear.hh"
#include "material_cohesive_linear_fatigue.hh"
#include "material_cohesive_linear_friction.hh"
#include "material_cohesive_bilinear.hh"
#include "material_cohesive_exponential.hh"
#endif
#define AKANTU_COHESIVE_MATERIAL_LIST \
((2, (cohesive_linear, MaterialCohesiveLinear ))) \
((2, (cohesive_linear_fatigue, MaterialCohesiveLinearFatigue ))) \
((2, (cohesive_linear_friction, MaterialCohesiveLinearFriction))) \
((2, (cohesive_bilinear , MaterialCohesiveBilinear ))) \
((2, (cohesive_exponential , MaterialCohesiveExponential )))
diff --git a/src/model/solid_mechanics/materials/material_core_includes.hh b/src/model/solid_mechanics/materials/material_core_includes.hh
index 1e6a4d135..2b35c35f2 100644
--- a/src/model/solid_mechanics/materials/material_core_includes.hh
+++ b/src/model/solid_mechanics/materials/material_core_includes.hh
@@ -1,69 +1,69 @@
/**
- * @file material_list.hh
+ * @file material_core_includes.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Oct 29 2013
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sat Jul 18 2015
*
* @brief List of materials for core package
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_CORE_INCLUDES_HH__
#define __AKANTU_MATERIAL_CORE_INCLUDES_HH__
/* -------------------------------------------------------------------------- */
/* Material list */
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_CMAKE_LIST_MATERIALS
// elastic materials
#include "material_elastic.hh"
#include "material_neohookean.hh"
#include "material_elastic_orthotropic.hh"
#include "material_elastic_linear_anisotropic.hh"
// visco-elastic materials
#include "material_standard_linear_solid_deviatoric.hh"
// damage laws
#include "material_marigo.hh"
#include "material_mazars.hh"
// small-deformation plasticity
#include "material_linear_isotropic_hardening.hh"
#endif
#define AKANTU_CORE_MATERIAL_LIST \
((2, (elastic , MaterialElastic ))) \
((2, (neohookean , MaterialNeohookean ))) \
((2, (elastic_orthotropic, MaterialElasticOrthotropic ))) \
((2, (elastic_anisotropic, MaterialElasticLinearAnisotropic ))) \
((2, (sls_deviatoric , MaterialStandardLinearSolidDeviatoric))) \
((2, (marigo , MaterialMarigo ))) \
((2, (mazars , MaterialMazars ))) \
((2, (plastic_linear_isotropic_hardening, MaterialLinearIsotropicHardening)))
#endif /* __AKANTU_MATERIAL_CORE_INCLUDES_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_damage.hh b/src/model/solid_mechanics/materials/material_damage/material_damage.hh
index 641fd7575..d7e0d76de 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_damage.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_damage.hh
@@ -1,112 +1,113 @@
/**
* @file material_damage.hh
*
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Mar 15 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sat Jul 11 2015
*
* @brief Material isotropic elastic
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material_elastic.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_DAMAGE_HH__
#define __AKANTU_MATERIAL_DAMAGE_HH__
__BEGIN_AKANTU__
template<UInt spatial_dimension, template<UInt> class Parent = MaterialElastic>
class MaterialDamage : public Parent<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialDamage(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialDamage() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void initMaterial();
/// compute the tangent stiffness matrix for an element type
virtual void computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost);
protected:
/// update the dissipated energy, must be called after the stress have been computed
virtual void updateEnergies(ElementType el_type, GhostType ghost_type);
/// compute the tangent stiffness matrix for a given quadrature point
inline void computeTangentModuliOnQuad(Matrix<Real> & tangent, Real & dam);
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// give the dissipated energy for the time step
Real getDissipatedEnergy() const;
virtual Real getEnergy(std::string type);
virtual Real getEnergy(std::string energy_id, ElementType type, UInt index) {
return Parent<spatial_dimension>::getEnergy(energy_id, type, index);
};
AKANTU_GET_MACRO_NOT_CONST(Damage, damage, ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO(Damage, damage, const ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real)
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// damage internal variable
InternalField<Real> damage;
/// dissipated energy
InternalField<Real> dissipated_energy;
/// contain the current value of @f$ \int_0^{\epsilon}\sigma(\omega)d\omega @f$ the dissipated energy
InternalField<Real> int_sigma;
};
__END_AKANTU__
#include "material_damage_tmpl.hh"
#endif /* __AKANTU_MATERIAL_DAMAGE_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
index b7a09446b..bf0ec8541 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
@@ -1,103 +1,104 @@
/**
* @file material_damage_non_local.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Aug 23 2012
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Wed Oct 21 2015
*
* @brief interface for non local damage material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material_non_local.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_DAMAGE_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_DAMAGE_NON_LOCAL_HH__
__BEGIN_AKANTU__
template<UInt spatial_dimension,
class MaterialDamageLocal>
class MaterialDamageNonLocal : public MaterialDamageLocal,
public MaterialNonLocal<spatial_dimension> {
public:
typedef MaterialNonLocal<spatial_dimension> MaterialNonLocalParent;
typedef MaterialDamageLocal MaterialDamageParent;
MaterialDamageNonLocal(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
MaterialDamageParent(model, id), MaterialNonLocalParent(model, id) { };
/* ------------------------------------------------------------------------ */
virtual void initMaterial() {
MaterialDamageParent::initMaterial();
MaterialNonLocalParent::initMaterial();
}
protected:
/* -------------------------------------------------------------------------- */
virtual void computeNonLocalStress(ElementType type, GhostType ghost_type = _not_ghost) = 0;
/* ------------------------------------------------------------------------ */
void computeNonLocalStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
if (elem_filter.getSize() == 0) continue;
computeNonLocalStress(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
public:
/* ------------------------------------------------------------------------ */
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
return MaterialNonLocalParent::getNbDataForElements(elements, tag) +
MaterialDamageParent::getNbDataForElements(elements, tag);
}
virtual inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
MaterialNonLocalParent::packElementData(buffer, elements, tag);
MaterialDamageParent::packElementData(buffer, elements, tag);
}
virtual inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
MaterialNonLocalParent::unpackElementData(buffer, elements, tag);
MaterialDamageParent::unpackElementData(buffer, elements, tag);
}
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_DAMAGE_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh b/src/model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
index 7a6e6d2f0..54e0dc2a6 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
@@ -1,172 +1,173 @@
/**
* @file material_damage_tmpl.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
- * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Mar 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Aug 18 2015
*
* @brief Specialization of the material class for the damage material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_damage.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension, template<UInt> class Parent>
MaterialDamage<spatial_dimension, Parent>::MaterialDamage(SolidMechanicsModel & model,
const ID & id) :
Material(model, id), Parent<spatial_dimension>(model, id),
damage("damage", *this),
dissipated_energy("damage dissipated energy", *this),
int_sigma("integral of sigma", *this) {
AKANTU_DEBUG_IN();
this->is_non_local = false;
this->use_previous_stress = true;
this->use_previous_gradu = true;
this->damage .initialize(1);
this->dissipated_energy.initialize(1);
this->int_sigma .initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension, template<UInt> class Parent>
void MaterialDamage<spatial_dimension, Parent>::initMaterial() {
AKANTU_DEBUG_IN();
Parent<spatial_dimension>::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the dissipated energy in each element by a trapezoidal approximation
* of
* @f$ Ed = \int_0^{\epsilon}\sigma(\omega)d\omega - \frac{1}{2}\sigma:\epsilon@f$
*/
template<UInt spatial_dimension, template<UInt> class Parent>
void MaterialDamage<spatial_dimension, Parent>::updateEnergies(ElementType el_type, GhostType ghost_type) {
Parent<spatial_dimension>::updateEnergies(el_type, ghost_type);
this->computePotentialEnergy(el_type, ghost_type);
Array<Real>::matrix_iterator epsilon_p =
this->gradu.previous(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator sigma_p =
this->stress.previous(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::const_scalar_iterator epot = this->potential_energy(el_type, ghost_type).begin();
Array<Real>::scalar_iterator ints = this->int_sigma(el_type, ghost_type).begin();
Array<Real>::scalar_iterator ed = this->dissipated_energy(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> delta_gradu_it(*gradu_it);
delta_gradu_it -= *epsilon_p;
Matrix<Real> sigma_h(sigma);
sigma_h += *sigma_p;
Real dint = .5 * sigma_h.doubleDot(delta_gradu_it);
*ints += dint;
*ed = *ints - *epot;
++epsilon_p;
++sigma_p;
++epot;
++ints;
++ed;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension, template<UInt> class Parent>
void MaterialDamage<spatial_dimension, Parent>::computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Parent<spatial_dimension>::computeTangentModuli(el_type, tangent_matrix, ghost_type);
Real * dam = this->damage(el_type, ghost_type).storage();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
computeTangentModuliOnQuad(tangent, *dam);
++dam;
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension, template<UInt> class Parent>
void MaterialDamage<spatial_dimension, Parent>::computeTangentModuliOnQuad(Matrix<Real> & tangent,
Real & dam) {
tangent *= (1-dam);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension, template<UInt> class Parent>
Real MaterialDamage<spatial_dimension, Parent>::getDissipatedEnergy() const {
AKANTU_DEBUG_IN();
Real de = 0.;
const Mesh & mesh = this->model->getFEEngine().getMesh();
/// integrate the dissipated energy for each type of elements
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, _not_ghost);
for(; it != end; ++it) {
de += this->model->getFEEngine().integrate(dissipated_energy(*it, _not_ghost), *it,
_not_ghost, this->element_filter(*it, _not_ghost));
}
AKANTU_DEBUG_OUT();
return de;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension, template<UInt> class Parent>
Real MaterialDamage<spatial_dimension, Parent>::getEnergy(std::string type) {
if(type == "dissipated") return getDissipatedEnergy();
else return Parent<spatial_dimension>::getEnergy(type);
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
index 947a01332..4088340ff 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
@@ -1,105 +1,106 @@
/**
* @file material_marigo.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Feb 02 2012
- * @date last modification: Fri Mar 21 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 08 2015
*
* @brief Specialization of the material class for the marigo material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_marigo.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialMarigo<spatial_dimension>::MaterialMarigo(SolidMechanicsModel & model,
const ID & id) :
Material(model, id),
MaterialDamage<spatial_dimension>(model, id),
Yd("Yd", *this), damage_in_y(false), yc_limit(false) {
AKANTU_DEBUG_IN();
this->registerParam("Sd", Sd, Real(5000.), _pat_parsable | _pat_modifiable);
this->registerParam("epsilon_c", epsilon_c, Real(0.), _pat_parsable, "Critical strain");
this->registerParam("Yc limit", yc_limit, false, _pat_internal, "As the material a critical Y");
this->registerParam("damage_in_y", damage_in_y, false, _pat_parsable, "Use threshold (1-D)Y");
this->registerParam("Yd", Yd, _pat_parsable, "Damaging energy threshold");
this->Yd.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMarigo<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialDamage<spatial_dimension>::initMaterial();
updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMarigo<spatial_dimension>::updateInternalParameters() {
MaterialDamage<spatial_dimension>::updateInternalParameters();
Yc = .5 * epsilon_c * this->E * epsilon_c;
if(std::abs(epsilon_c) > std::numeric_limits<Real>::epsilon()) yc_limit = true;
else yc_limit = false;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMarigo<spatial_dimension>::computeStress(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::scalar_iterator dam = this->damage(el_type, ghost_type).begin();
Array<Real>::scalar_iterator Yd_q = this->Yd(el_type, ghost_type) .begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Real Y = 0.;
computeStressOnQuad(grad_u, sigma, *dam, Y, *Yd_q);
++dam;
++Yd_q;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
INSTANTIATE_MATERIAL(MaterialMarigo);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo.hh b/src/model/solid_mechanics/materials/material_damage/material_marigo.hh
index b6d42e397..e2ccf7cf1 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo.hh
@@ -1,137 +1,138 @@
/**
* @file material_marigo.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Feb 02 2012
- * @date last modification: Wed Nov 13 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Marigo damage law
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material_damage.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_MARIGO_HH__
#define __AKANTU_MATERIAL_MARIGO_HH__
__BEGIN_AKANTU__
/**
* Material marigo
*
* parameters in the material files :
* - Yd : (default: 50)
* - Sd : (default: 5000)
* - Ydrandomness : (default:0)
*/
template<UInt spatial_dimension>
class MaterialMarigo : public MaterialDamage<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialMarigo(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialMarigo() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void initMaterial();
virtual void updateInternalParameters();
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
protected:
/// constitutive law for a given quadrature point
inline void computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & dam,
Real & Y,
Real & Ydq);
inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma,
Real & dam,
Real & Y,
Real & Ydq);
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
public:
inline virtual UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
inline virtual void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
inline virtual void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// resistance to damage
RandomInternalField<Real> Yd;
/// damage threshold
Real Sd;
/// critical epsilon when the material is considered as broken
Real epsilon_c;
Real Yc;
bool damage_in_y;
bool yc_limit;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_marigo_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_MARIGO_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
index 2c2e83597..873b47356 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
@@ -1,122 +1,123 @@
/**
* @file material_marigo_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Feb 02 2012
- * @date last modification: Tue Jun 24 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief Implementation of the inline functions of the material marigo
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline void
MaterialMarigo<spatial_dimension>::computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & dam,
Real & Y,
Real &Ydq) {
MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
Y = 0;
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
Y += sigma(i,j) * (grad_u(i, j) + grad_u(j, i))/2.;
}
}
Y *= 0.5;
if(damage_in_y) Y *= (1 - dam);
if(yc_limit) Y = std::min(Y, Yc);
if(!this->is_non_local) {
computeDamageAndStressOnQuad(sigma, dam, Y, Ydq);
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline void
MaterialMarigo<spatial_dimension>::computeDamageAndStressOnQuad(Matrix<Real> & sigma,
Real & dam,
Real & Y,
Real &Ydq) {
Real Fd = Y - Ydq - Sd * dam;
if (Fd > 0) dam = (Y - Ydq) / Sd;
dam = std::min(dam, Real(1.));
sigma *= 1-dam;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline UInt MaterialMarigo<spatial_dimension>::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
if(tag == _gst_smm_init_mat) {
size += sizeof(Real) * this->getModel().getNbIntegrationPoints(elements);
}
size += MaterialDamage<spatial_dimension>::getNbDataForElements(elements, tag);
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline void MaterialMarigo<spatial_dimension>::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
if(tag == _gst_smm_init_mat) {
this->packElementDataHelper(Yd, buffer, elements);
}
MaterialDamage<spatial_dimension>::packElementData(buffer, elements, tag);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline void MaterialMarigo<spatial_dimension>::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
if(tag == _gst_smm_init_mat) {
this->unpackElementDataHelper(Yd, buffer, elements);
}
MaterialDamage<spatial_dimension>::unpackElementData(buffer, elements, tag);
AKANTU_DEBUG_OUT();
}
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
index 5cdaefb9c..f9c23eb9b 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
@@ -1,98 +1,99 @@
/**
* @file material_marigo_non_local.hh
*
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Aug 31 2011
- * @date last modification: Wed Nov 13 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief Marigo non-local description
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material_damage_non_local.hh"
#include "material_marigo.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/**
* Material Marigo
*
* parameters in the material files :
*/
template<UInt spatial_dimension>
class MaterialMarigoNonLocal : public MaterialDamageNonLocal<spatial_dimension, MaterialMarigo<spatial_dimension> > {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef MaterialDamageNonLocal<spatial_dimension, MaterialMarigo<spatial_dimension> > MaterialMarigoNonLocalParent;
MaterialMarigoNonLocal(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialMarigoNonLocal() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void initMaterial();
protected:
/// constitutive law
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
void computeNonLocalStress(ElementType type, GhostType ghost_type = _not_ghost);
private:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Y, Y, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
InternalField<Real> Y;
InternalField<Real> Ynl;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_marigo_non_local_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local_inline_impl.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local_inline_impl.cc
index c2d2a6b36..1a0284831 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local_inline_impl.cc
@@ -1,104 +1,105 @@
/**
* @file material_marigo_non_local_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Jun 15 2012
- * @date last modification: Wed Nov 13 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief Marigo non-local inline function implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#if defined(AKANTU_DEBUG_TOOLS)
#include "aka_debug_tools.hh"
#include <string>
#endif
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialMarigoNonLocal<spatial_dimension>::MaterialMarigoNonLocal(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
MaterialMarigoNonLocalParent(model, id),
Y("Y", *this), Ynl("Y non local", *this) {
AKANTU_DEBUG_IN();
this->is_non_local = true;
this->Y.initialize(1);
this->Ynl.initialize(1);
this->model->getNonLocalManager().registerNonLocalVariable(this->Y.getName(), Ynl.getName(), 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMarigoNonLocal<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialMarigoNonLocalParent::initMaterial();
this->model->getNonLocalManager().nonLocalVariableToNeighborhood(Ynl.getName(), this->name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMarigoNonLocal<spatial_dimension>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = this->damage(el_type, ghost_type).storage();
Real * Yt = this->Y(el_type, ghost_type).storage();
Real * Ydq = this->Yd(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
MaterialMarigo<spatial_dimension>::computeStressOnQuad(grad_u, sigma,
*dam, *Yt, *Ydq);
++dam;
++Yt;
++Ydq;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMarigoNonLocal<spatial_dimension>::computeNonLocalStress(ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = this->damage(type, ghost_type).storage();
Real * Ydq = this->Yd(type, ghost_type).storage();
Real * Ynlt = this->Ynl(type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(type, ghost_type);
this->computeDamageAndStressOnQuad(sigma, *dam, *Ynlt, *Ydq);
++dam;
++Ynlt;
++Ydq;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars.cc b/src/model/solid_mechanics/materials/material_damage/material_mazars.cc
index 86ee96a34..0929b493e 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars.cc
@@ -1,83 +1,84 @@
/**
* @file material_mazars.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Apr 06 2011
- * @date last modification: Mon Feb 10 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Aug 18 2015
*
* @brief Specialization of the material class for the damage material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_mazars.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialMazars<spatial_dimension>::MaterialMazars(SolidMechanicsModel & model,
const ID & id) :
Material(model, id),
MaterialDamage<spatial_dimension>(model, id),
K0("K0", *this),
damage_in_compute_stress(true) {
AKANTU_DEBUG_IN();
this->registerParam("K0" , K0 , _pat_parsable, "K0");
this->registerParam("At" , At , Real(0.8 ), _pat_parsable, "At");
this->registerParam("Ac" , Ac , Real(1.4 ), _pat_parsable, "Ac");
this->registerParam("Bc" , Bc , Real(1900. ), _pat_parsable, "Bc");
this->registerParam("Bt" , Bt , Real(12000.), _pat_parsable, "Bt");
this->registerParam("beta", beta, Real(1.06 ), _pat_parsable, "beta");
this->K0.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazars<spatial_dimension>::computeStress(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = this->damage(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Real Ehat = 0;
computeStressOnQuad(grad_u, sigma, *dam, Ehat);
++dam;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialMazars);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars.hh b/src/model/solid_mechanics/materials/material_damage/material_mazars.hh
index 1bb457fd4..fe9da5555 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars.hh
@@ -1,128 +1,129 @@
/**
* @file material_mazars.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Apr 06 2011
- * @date last modification: Fri Dec 20 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Material Following the Mazars law for damage evolution
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material_damage.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_MAZARS_HH__
#define __AKANTU_MATERIAL_MAZARS_HH__
__BEGIN_AKANTU__
/**
* Material Mazars
*
* parameters in the material files :
* - rho : density (default: 0)
* - E : Young's modulus (default: 0)
* - nu : Poisson's ratio (default: 1/2)
* - K0 : Damage threshold
* - At : Parameter damage traction 1
* - Bt : Parameter damage traction 2
* - Ac : Parameter damage compression 1
* - Bc : Parameter damage compression 2
* - beta : Parameter for shear
*/
template<UInt spatial_dimension>
class MaterialMazars : public MaterialDamage<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialMazars(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialMazars() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
protected:
/// constitutive law for a given quadrature point
inline void computeStressOnQuad(const Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & damage,
Real & Ehat);
inline void computeDamageAndStressOnQuad(const Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & damage,
Real & Ehat);
inline void computeDamageOnQuad(const Real & epsilon_equ,
const Matrix<Real> & sigma,
const Vector<Real> & epsilon_princ,
Real & dam);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// damage threshold
RandomInternalField<Real> K0;
///parameter damage traction 1
Real At ;
///parameter damage traction 2
Real Bt ;
///parameter damage compression 1
Real Ac ;
///parameter damage compression 2
Real Bc ;
///parameter for shear
Real beta ;
/// specify the variable to average false = ehat, true = damage (only valid for non local version)
bool damage_in_compute_stress;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_mazars_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_MAZARS_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc b/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
index 58d8a993a..716d2e9af 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
@@ -1,153 +1,154 @@
/**
* @file material_mazars_inline_impl.cc
*
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Apr 06 2011
- * @date last modification: Wed Mar 13 2013
+ * @date last modification: Tue Aug 04 2015
*
* @brief Implementation of the inline functions of the material damage
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline void
MaterialMazars<spatial_dimension>::computeStressOnQuad(const Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & dam,
Real & Ehat) {
Matrix<Real> epsilon(3, 3);
epsilon.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
epsilon(i,j) = .5*(grad_u(i,j) + grad_u(j,i));
Vector<Real> Fdiag(3);
Math::matrixEig(3, epsilon.storage(), Fdiag.storage());
Ehat = 0.;
for (UInt i = 0; i < 3; ++i) {
Real epsilon_p = std::max(Real(0.), Fdiag(i));
Ehat += epsilon_p * epsilon_p;
}
Ehat = sqrt(Ehat);
MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
if(damage_in_compute_stress) {
computeDamageOnQuad(Ehat, sigma, Fdiag, dam);
}
if(!this->is_non_local) {
computeDamageAndStressOnQuad(grad_u, sigma, dam, Ehat);
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline void
MaterialMazars<spatial_dimension>::computeDamageAndStressOnQuad(const Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & dam,
Real & Ehat) {
if(!damage_in_compute_stress) {
Vector<Real> Fdiag(3);
Fdiag.clear();
Matrix<Real> epsilon(3, 3);
epsilon.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
epsilon(i,j) = .5*(grad_u(i,j) + grad_u(j,i));
Math::matrixEig(3, epsilon.storage(), Fdiag.storage());
computeDamageOnQuad(Ehat, sigma, Fdiag, dam);
}
sigma *= 1 - dam;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline void
MaterialMazars<spatial_dimension>::computeDamageOnQuad(const Real & epsilon_equ,
__attribute__((unused)) const Matrix<Real> & sigma,
const Vector<Real> & epsilon_princ,
Real & dam) {
Real Fs = epsilon_equ - K0;
if (Fs > 0.) {
Real dam_t;
Real dam_c;
dam_t = 1 - K0*(1 - At)/epsilon_equ - At*(exp(-Bt*(epsilon_equ - K0)));
dam_c = 1 - K0*(1 - Ac)/epsilon_equ - Ac*(exp(-Bc*(epsilon_equ - K0)));
Real Cdiag;
Cdiag = this->E*(1-this->nu)/((1+this->nu)*(1-2*this->nu));
Vector<Real> sigma_princ(3);
sigma_princ(0) = Cdiag*epsilon_princ(0) + this->lambda*(epsilon_princ(1) + epsilon_princ(2));
sigma_princ(1) = Cdiag*epsilon_princ(1) + this->lambda*(epsilon_princ(0) + epsilon_princ(2));
sigma_princ(2) = Cdiag*epsilon_princ(2) + this->lambda*(epsilon_princ(1) + epsilon_princ(0));
Vector<Real> sigma_p(3);
for (UInt i = 0; i < 3; i++) sigma_p(i) = std::max(Real(0.), sigma_princ(i));
sigma_p *= 1. - dam;
Real trace_p = this->nu / this->E * (sigma_p(0) + sigma_p(1) + sigma_p(2));
Real alpha_t = 0;
for (UInt i = 0; i < 3; ++i) {
Real epsilon_t = (1 + this->nu)/this->E * sigma_p(i) - trace_p;
Real epsilon_p = std::max(Real(0.), epsilon_princ(i));
alpha_t += epsilon_t * epsilon_p;
}
alpha_t /= epsilon_equ * epsilon_equ;
alpha_t = std::min(alpha_t, Real(1.));
Real alpha_c = 1. - alpha_t;
alpha_t = std::pow(alpha_t, beta);
alpha_c = std::pow(alpha_c, beta);
Real damtemp;
damtemp = alpha_t * dam_t + alpha_c * dam_c;
dam = std::max(damtemp, dam);
dam = std::min(dam, Real(1.));
}
}
/* -------------------------------------------------------------------------- */
// template<UInt spatial_dimension>
// inline void MaterialMazars<spatial_dimension>::computeTangentModuliOnQuad(Matrix<Real> & tangent) {
// MaterialElastic<spatial_dimension>::computeTangentModuliOnQuad(tangent);
// tangent *= (1-dam);
// }
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
index abc0c22fb..46ea3c128 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
@@ -1,149 +1,150 @@
/**
* @file material_mazars_non_local.cc
*
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Oct 03 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief Specialization of the material class for the non-local mazars material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_mazars_non_local.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialMazarsNonLocal<spatial_dimension>::MaterialMazarsNonLocal(SolidMechanicsModel & model,
const ID & id) :
Material(model, id),
MaterialMazars<spatial_dimension>(model, id),
MaterialNonLocalParent(model, id),
Ehat("epsilon_equ", *this) {
AKANTU_DEBUG_IN();
this->is_non_local = true;
this->Ehat.initialize(1);
this->registerParam("average_on_damage", this->damage_in_compute_stress, false,
_pat_parsable | _pat_modifiable, "Is D the non local variable");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazarsNonLocal<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialMazars<spatial_dimension>::initMaterial();
MaterialNonLocalParent::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazarsNonLocal<spatial_dimension>::computeStress(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * damage = this->damage(el_type, ghost_type).storage();
Real * epsilon_equ = this->Ehat(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
MaterialMazars<spatial_dimension>::computeStressOnQuad(grad_u, sigma,
*damage,
*epsilon_equ);
++damage;
++epsilon_equ;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazarsNonLocal<spatial_dimension>::computeNonLocalStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
InternalField<Real> nl_var("Non local variable", *this);
nl_var.initialize(1);
// if(this->damage_in_compute_stress)
// this->weightedAvergageOnNeighbours(this->damage, nl_var, 1);
// else
// this->weightedAvergageOnNeighbours(this->Ehat, nl_var, 1);
// Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(spatial_dimension, ghost_type);
// Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(spatial_dimension, ghost_type);
// for(; it != last_type; ++it) {
// this->computeNonLocalStress(nl_var(*it, ghost_type), *it, ghost_type);
// }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazarsNonLocal<spatial_dimension>::computeNonLocalStress(Array<Real> & non_loc_var,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * damage;
Real * epsilon_equ;
if(this->damage_in_compute_stress){
damage = non_loc_var.storage();
epsilon_equ = this->Ehat(el_type, ghost_type).storage();
} else {
damage = this->damage(el_type, ghost_type).storage();
epsilon_equ = non_loc_var.storage();
}
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->computeDamageAndStressOnQuad(grad_u, sigma, *damage, *epsilon_equ);
++damage;
++epsilon_equ;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazarsNonLocal<spatial_dimension>::nonLocalVariableToNeighborhood() {
}
INSTANTIATE_MATERIAL(MaterialMazarsNonLocal);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
index b9a9b39ec..1b2be905a 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
@@ -1,102 +1,103 @@
/**
* @file material_mazars_non_local.hh
*
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Oct 03 2011
- * @date last modification: Thu Mar 27 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 08 2015
*
* @brief Mazars non-local description
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material_mazars.hh"
#include "material_non_local.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__
__BEGIN_AKANTU__
/**
* Material Mazars Non local
*
* parameters in the material files :
*/
template<UInt spatial_dimension>
class MaterialMazarsNonLocal : public MaterialMazars<spatial_dimension>,
public MaterialNonLocal<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef MaterialNonLocal<spatial_dimension> MaterialNonLocalParent;
MaterialMazarsNonLocal(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialMazarsNonLocal() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void initMaterial();
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// constitutive law
void computeNonLocalStresses(GhostType ghost_type = _not_ghost);
void computeNonLocalStress(Array<Real> & Ehatnl,
ElementType el_type,
GhostType ghost_type = _not_ghost);
protected:
/// associate the non-local variables of the material to their neighborhoods
virtual void nonLocalVariableToNeighborhood();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// the ehat per quadrature points to perform the averaging
InternalField<Real> Ehat;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "material_mazars_non_local_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic.cc b/src/model/solid_mechanics/materials/material_elastic.cc
index d6250fd6b..af089aefb 100644
--- a/src/model/solid_mechanics/materials/material_elastic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic.cc
@@ -1,248 +1,249 @@
/**
* @file material_elastic.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Tue Jul 27 2010
- * @date last modification: Tue Sep 16 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief Specialization of the material class for the elastic material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_elastic.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt dim>
MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
Parent(model, id) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model,
UInt a_dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id) :
Material(model, dim, mesh, fe_engine, id),
Parent(model, dim, mesh, fe_engine, id) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialElastic<dim>::initialize() {
this->registerParam("lambda" ,lambda , _pat_readable, "First Lamé coefficient" );
this->registerParam("mu" ,mu , _pat_readable, "Second Lamé coefficient");
this->registerParam("kapa" ,kpa , _pat_readable, "Bulk coefficient" );
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialElastic<dim>::initMaterial() {
AKANTU_DEBUG_IN();
Parent::initMaterial();
if (dim == 1) this->nu = 0.;
this->updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialElastic<dim>::updateInternalParameters() {
MaterialThermal<dim>::updateInternalParameters();
this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2*this->nu));
this->mu = this->E / (2 * (1 + this->nu));
this->kpa = this->lambda + 2./3. * this->mu;
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialElastic<2>::updateInternalParameters() {
MaterialThermal<2>::updateInternalParameters();
this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2*this->nu));
this->mu = this->E / (2 * (1 + this->nu));
if(this->plane_stress) this->lambda = this->nu * this->E / ((1 + this->nu)*(1 - this->nu));
this->kpa = this->lambda + 2./3. * this->mu;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Parent::computeStress(el_type, ghost_type);
Array<Real>::const_scalar_iterator sigma_th_it = this->sigma_th(el_type, ghost_type).begin();
if (!this->finite_deformation) {
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
const Real & sigma_th = *sigma_th_it;
this->computeStressOnQuad(grad_u, sigma, sigma_th);
++sigma_th_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
} else {
/// finite gradus
Matrix<Real> E(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
/// compute E
this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
const Real & sigma_th = *sigma_th_it;
/// compute second Piola-Kirchhoff stress tensor
this->computeStressOnQuad(E, sigma, sigma_th);
++sigma_th_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
Array<Real> & tangent_matrix,
__attribute__((unused)) GhostType ghost_type) {
AKANTU_DEBUG_IN();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
this->computeTangentModuliOnQuad(tangent);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialElastic<spatial_dimension>::getPushWaveSpeed(__attribute__((unused)) const Element & element) const {
return sqrt((lambda + 2*mu)/this->rho);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialElastic<spatial_dimension>::getShearWaveSpeed(__attribute__((unused)) const Element & element) const {
return sqrt(mu/this->rho);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computePotentialEnergy(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialThermal<spatial_dimension>::computePotentialEnergy(el_type, ghost_type);
if(ghost_type != _not_ghost) return;
Array<Real>::scalar_iterator epot = this->potential_energy(el_type, ghost_type).begin();
if (!this->finite_deformation) {
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->computePotentialEnergyOnQuad(grad_u, sigma, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
} else {
Matrix<Real> E(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
this->computePotentialEnergyOnQuad(E, sigma, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computePotentialEnergyByElement(ElementType type, UInt index,
Vector<Real> & epot_on_quad_points) {
Array<Real>::matrix_iterator gradu_it =
this->gradu(type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator gradu_end =
this->gradu(type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator stress_it =
this->stress(type).begin(spatial_dimension,
spatial_dimension);
if (this->finite_deformation)
stress_it = this->piola_kirchhoff_2(type).begin(spatial_dimension,
spatial_dimension);
UInt nb_quadrature_points = this->model->getFEEngine().getNbIntegrationPoints(type);
gradu_it += index*nb_quadrature_points;
gradu_end += (index+1)*nb_quadrature_points;
stress_it += index*nb_quadrature_points;
Real * epot_quad = epot_on_quad_points.storage();
Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
for(;gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
if (this->finite_deformation)
this->template gradUToGreenStrain<spatial_dimension>(*gradu_it, grad_u);
else
grad_u.copy(*gradu_it);
this->computePotentialEnergyOnQuad(grad_u, *stress_it, *epot_quad);
}
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialElastic);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_elastic.hh b/src/model/solid_mechanics/materials/material_elastic.hh
index a4e81fce5..90ba0261e 100644
--- a/src/model/solid_mechanics/materials/material_elastic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic.hh
@@ -1,156 +1,157 @@
/**
* @file material_elastic.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Aug 04 2010
- * @date last modification: Tue Sep 16 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Nov 15 2015
*
* @brief Material isotropic elastic
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material_thermal.hh"
#include "plane_stress_toolbox.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_ELASTIC_HH__
#define __AKANTU_MATERIAL_ELASTIC_HH__
__BEGIN_AKANTU__
/**
* Material elastic isotropic
*
* parameters in the material files :
* - E : Young's modulus (default: 0)
* - nu : Poisson's ratio (default: 1/2)
* - Plane_Stress : if 0: plane strain, else: plane stress (default: 0)
*/
template<UInt spatial_dimension>
class MaterialElastic : public PlaneStressToolbox< spatial_dimension,
MaterialThermal<spatial_dimension> > {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
private:
typedef PlaneStressToolbox< spatial_dimension,
MaterialThermal<spatial_dimension> > Parent;
public:
MaterialElastic(SolidMechanicsModel & model, const ID & id = "");
MaterialElastic(SolidMechanicsModel & model,
UInt dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id = "");
virtual ~MaterialElastic() {}
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 = _not_ghost);
/// compute the tangent stiffness matrix for an element type
virtual void computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost);
/// compute the elastic potential energy
virtual void computePotentialEnergy(ElementType el_type,
GhostType ghost_type = _not_ghost);
virtual void computePotentialEnergyByElement(ElementType type, UInt index,
Vector<Real> & epot_on_quad_points);
/// compute the p-wave speed in the material
virtual Real getPushWaveSpeed(const Element & element) const;
/// compute the s-wave speed in the material
virtual Real getShearWaveSpeed(const Element & element) const;
protected:
/// constitutive law for a given quadrature point
inline void computeStressOnQuad(const Matrix<Real> & grad_u,
Matrix<Real> & sigma,
const Real sigma_th = 0) const;
/// compute the tangent stiffness matrix for an element
inline void computeTangentModuliOnQuad(Matrix<Real> & tangent) const;
/// recompute the lame coefficient if E or nu changes
virtual void updateInternalParameters();
static inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & sigma,
Real & epot);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get first Lame constant
AKANTU_GET_MACRO(Lambda, lambda, Real);
/// get second Lame constant
AKANTU_GET_MACRO(Mu, mu, Real);
/// get bulk modulus
AKANTU_GET_MACRO(Kappa, kpa, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// First Lamé coefficient
Real lambda;
/// Second Lamé coefficient (shear modulus)
Real mu;
/// Bulk modulus
Real kpa;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_elastic_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_ELASTIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc b/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc
index 829b7ac36..b897d4d91 100644
--- a/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc
@@ -1,107 +1,108 @@
/**
* @file material_elastic_inline_impl.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 04 2010
- * @date last modification: Mon Apr 07 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief Implementation of the inline functions of the material elastic
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline void MaterialElastic<spatial_dimension>::computeStressOnQuad(const Matrix<Real> & grad_u,
Matrix<Real> & sigma,
const Real sigma_th) const {
Real trace = grad_u.trace(); // trace = (\nabla u)_{kk}
// \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla u_{ij} + \nabla u_{ji})
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
sigma(i, j) = (i == j)*lambda*trace + mu*(grad_u(i, j) + grad_u(j, i)) + (i == j) * sigma_th;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
inline void MaterialElastic<1>::computeStressOnQuad(const Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real sigma_th) const {
sigma(0, 0) = this->E * grad_u(0, 0) + sigma_th;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
inline void MaterialElastic<spatial_dimension>::computeTangentModuliOnQuad(Matrix<Real> & tangent) const {
UInt n = tangent.cols();
//Real Ep = E/((1+nu)*(1-2*nu));
Real Miiii = lambda + 2*mu;
Real Miijj = lambda;
Real Mijij = mu;
if(spatial_dimension == 1)
tangent(0, 0) = this->E;
else
tangent(0, 0) = Miiii;
// test of dimension should by optimized out by the compiler due to the template
if(spatial_dimension >= 2) {
tangent(1, 1) = Miiii;
tangent(0, 1) = Miijj;
tangent(1, 0) = Miijj;
tangent(n - 1, n - 1) = Mijij;
}
if(spatial_dimension == 3) {
tangent(2, 2) = Miiii;
tangent(0, 2) = Miijj;
tangent(1, 2) = Miijj;
tangent(2, 0) = Miijj;
tangent(2, 1) = Miijj;
tangent(3, 3) = Mijij;
tangent(4, 4) = Mijij;
}
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialElastic<dim>::computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & sigma,
Real & epot) {
epot = .5 * sigma.doubleDot(grad_u);
}
/* -------------------------------------------------------------------------- */
template<>
inline void MaterialElastic<1>::computeTangentModuliOnQuad(Matrix<Real> & tangent) const {
tangent(0, 0) = E;
}
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 90c43eb42..137737be7 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
@@ -1,332 +1,332 @@
/**
* @file material_elastic_linear_anisotropic.cc
*
* @author Till Junge <till.junge@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Sep 25 2013
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Anisotropic elastic material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "material_elastic_linear_anisotropic.hh"
#include "solid_mechanics_model.hh"
#include <algorithm>
#include <sstream>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialElasticLinearAnisotropic<spatial_dimension>::
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<Real>(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<Real>(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<Real>(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<UInt spatial_dimension>
MaterialElasticLinearAnisotropic<spatial_dimension>::~MaterialElasticLinearAnisotropic() {
for (UInt i = 0 ; i < spatial_dimension ; ++i) {
delete this->dir_vecs[i];
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticLinearAnisotropic<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticLinearAnisotropic<spatial_dimension>::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<UInt Dim>
void MaterialElasticLinearAnisotropic<Dim>::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<Real> 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<Real> test_axis(3);
Vector<Real> 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<Real>::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<Real> rotator(Dim * Dim, Dim * Dim);
Matrix<Real> 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);
}
}
}
}
// create the full rotated matrix
Matrix<Real> 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);
}
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticLinearAnisotropic<spatial_dimension>::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<Real>::iterator< Matrix<Real> > gradu_it =
this->gradu(el_type, ghost_type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::iterator< Matrix<Real> > 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<Real> voigt_strains(this->voigt_h.size, nb_quad_pts);
Matrix<Real> voigt_stresses(this->voigt_h.size, nb_quad_pts);
// copy strains
Matrix<Real> strain(spatial_dimension, spatial_dimension);
for (UInt q = 0; gradu_it != gradu_end ; ++gradu_it, ++q) {
Matrix<Real> & 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<Real> strain_rate(0, spatial_dimension * spatial_dimension,
"strain_rate");
Array<Real> & velocity = this->model->getVelocity();
const Array<UInt> & 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<Real>::matrix_iterator gradu_dot_it = strain_rate.begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator gradu_dot_end = strain_rate.end(spatial_dimension,
spatial_dimension);
Matrix<Real> strain_dot(spatial_dimension, spatial_dimension);
for (UInt q = 0; gradu_dot_it != gradu_dot_end ; ++gradu_dot_it, ++q) {
Matrix<Real> & 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<Real>::iterator< Matrix<Real> > stress_it =
this->stress(el_type, ghost_type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::iterator< Matrix<Real> > 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<Real> & 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<UInt spatial_dimension>
void MaterialElasticLinearAnisotropic<spatial_dimension>::computeTangentModuli(const ElementType & el_type,
Array<Real> & 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<UInt spatial_dimension>
Real MaterialElasticLinearAnisotropic<spatial_dimension>::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_elastic_linear_anisotropic.hh b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
index 504e407f1..60321279a 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
@@ -1,120 +1,121 @@
/**
* @file material_elastic_linear_anisotropic.hh
*
* @author Till Junge <till.junge@epfl.ch>
*
- * @date creation: Wed Sep 25 2013
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Aug 18 2015
*
* @brief Orthotropic elastic material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material.hh"
#include "material_elastic.hh"
#include <vector>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_HH__
#define __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_HH__
__BEGIN_AKANTU__
/**
* General linear anisotropic elastic material
* The only constraint on the elastic tensor is that it can be represented
* as a symmetric 6x6 matrix (3D) or 3x3 (2D).
*
* parameters in the material files :
* - rho : density (default: 0)
* - C_ij : entry on the stiffness
*/
template<UInt Dim>
class MaterialElasticLinearAnisotropic : public virtual Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialElasticLinearAnisotropic(SolidMechanicsModel & model, const ID & id = "",
bool symmetric = true);
~MaterialElasticLinearAnisotropic();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void initMaterial();
/// constitutive law for all element of a type
virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// compute the tangent stiffness matrix for an element type
void computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost);
virtual void updateInternalParameters();
protected:
// compute C from Cprime
void rotateCprime();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// compute max wave celerity
virtual Real getCelerity(const Element & element) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
const static VoigtHelper<Dim> voigt_h;
/// direction matrix and vectors
std::vector<Vector<Real>*> dir_vecs;
Matrix<Real> rot_mat;
/// Elastic stiffness tensor in material frame and full vectorised notation
Matrix<Real> Cprime;
/// Elastic stiffness tensor in voigt notation
Matrix<Real> C;
/// eigenvalues of stiffness tensor
Vector<Real> eigC;
bool symmetric;
/// viscous proportion
Real alpha;
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
index c861535df..e0a992e4e 100644
--- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
@@ -1,212 +1,213 @@
/**
* @file material_elastic_orthotropic.cc
*
* @author Till Junge <till.junge@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Tue May 08 2012
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief Orthotropic elastic material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_elastic_orthotropic.hh"
#include "solid_mechanics_model.hh"
#include <algorithm>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt Dim>
MaterialElasticOrthotropic<Dim>::MaterialElasticOrthotropic(SolidMechanicsModel & model,
const ID & id) :
Material(model, id),
MaterialElasticLinearAnisotropic<Dim>(model, id) {
AKANTU_DEBUG_IN();
this->registerParam("E1", E1 , Real(0.), _pat_parsmod, "Young's modulus (n1)");
this->registerParam("E2", E2 , Real(0.), _pat_parsmod, "Young's modulus (n2)");
this->registerParam("nu12", nu12, Real(0.), _pat_parsmod, "Poisson's ratio (12)");
this->registerParam("G12", G12 , Real(0.), _pat_parsmod, "Shear modulus (12)");
if (Dim > 2) {
this->registerParam("E3" , E3 , Real(0.), _pat_parsmod, "Young's modulus (n3)");
this->registerParam("nu13", nu13, Real(0.), _pat_parsmod, "Poisson's ratio (13)");
this->registerParam("nu23", nu23, Real(0.), _pat_parsmod, "Poisson's ratio (23)");
this->registerParam("G13" , G13 , Real(0.), _pat_parsmod, "Shear modulus (13)");
this->registerParam("G23" , G23 , Real(0.), _pat_parsmod, "Shear modulus (23)");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt Dim>
MaterialElasticOrthotropic<Dim>::~MaterialElasticOrthotropic() {
}
/* -------------------------------------------------------------------------- */
template<UInt Dim>
void MaterialElasticOrthotropic<Dim>::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline Real vector_norm(Vector<Real> & vec) {
Real norm = 0;
for (UInt i = 0 ; i < vec.size() ; ++i) {
norm += vec(i)*vec(i);
}
return std::sqrt(norm);
}
/* -------------------------------------------------------------------------- */
template<UInt Dim>
void MaterialElasticOrthotropic<Dim>::updateInternalParameters() {
/* 1) construction of temporary material frame stiffness tensor------------ */
// http://solidmechanics.org/Text/Chapter3_2/Chapter3_2.php#Sect3_2_13
Real nu21 = nu12 * E2 / E1;
Real nu31 = nu13 * E3 / E1;
Real nu32 = nu23 * E3 / E2;
// Full (i.e. dim^2 by dim^2) stiffness tensor in material frame
if (Dim == 1) {
AKANTU_DEBUG_ERROR("Dimensions 1 not implemented: makes no sense to have orthotropy for 1D");
}
Real Gamma;
if (Dim == 3)
Gamma = 1/(1 - nu12 * nu21 - nu23 * nu32 - nu31 * nu13 - 2 * nu21 * nu32 * nu13);
if (Dim == 2)
Gamma = 1/(1 - nu12 * nu21);
// Lamé's first parameters
this->Cprime(0, 0) = E1 * (1 - nu23 * nu32) * Gamma;
this->Cprime(1, 1) = E2 * (1 - nu13 * nu31) * Gamma;
if (Dim == 3)
this->Cprime(2, 2) = E3 * (1 - nu12 * nu21) * Gamma;
// normalised poisson's ratio's
this->Cprime(1, 0) = this->Cprime(0, 1) = E1 * (nu21 + nu31 * nu23) * Gamma;
if (Dim == 3) {
this->Cprime(2, 0) = this->Cprime(0, 2) = E1 * (nu31 + nu21 * nu32) * Gamma;
this->Cprime(2, 1) = this->Cprime(1, 2) = E2 * (nu32 + nu12 * nu31) * Gamma;
}
// Lamé's second parameters (shear moduli)
if (Dim == 3) {
this->Cprime(3, 3) = G23;
this->Cprime(4, 4) = G13;
this->Cprime(5, 5) = G12;
}
else
this->Cprime(2, 2) = G12;
/* 1) rotation of C into the global frame */
this->rotateCprime();
this->C.eig(this->eigC);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialElasticOrthotropic<dim>::computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & sigma,
Real & epot) {
epot = .5 * sigma.doubleDot(grad_u);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticOrthotropic<spatial_dimension>::computePotentialEnergy(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Material::computePotentialEnergy(el_type, ghost_type);
AKANTU_DEBUG_ASSERT(!this->finite_deformation,"finite deformation not possible in material orthotropic (TO BE IMPLEMENTED)");
if(ghost_type != _not_ghost) return;
Array<Real>::scalar_iterator epot = this->potential_energy(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computePotentialEnergyOnQuad(grad_u, sigma, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticOrthotropic<spatial_dimension>::computePotentialEnergyByElement(ElementType type, UInt index,
Vector<Real> & epot_on_quad_points) {
AKANTU_DEBUG_ASSERT(!this->finite_deformation,"finite deformation not possible in material orthotropic (TO BE IMPLEMENTED)");
Array<Real>::matrix_iterator gradu_it =
this->gradu(type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator gradu_end =
this->gradu(type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator stress_it =
this->stress(type).begin(spatial_dimension,
spatial_dimension);
UInt nb_quadrature_points = this->model->getFEEngine().getNbIntegrationPoints(type);
gradu_it += index*nb_quadrature_points;
gradu_end += (index+1)*nb_quadrature_points;
stress_it += index*nb_quadrature_points;
Real * epot_quad = epot_on_quad_points.storage();
Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
for(;gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
grad_u.copy(*gradu_it);
computePotentialEnergyOnQuad(grad_u, *stress_it, *epot_quad);
}
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialElasticOrthotropic);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh b/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh
index e413df7a0..53922cd66 100644
--- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh
@@ -1,148 +1,149 @@
/**
* @file material_elastic_orthotropic.hh
*
* @author Till Junge <till.junge@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Tue May 08 2012
- * @date last modification: Tue Aug 19 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Orthotropic elastic material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material_elastic_linear_anisotropic.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_ELASTIC_ORTHOTROPIC_HH__
#define __AKANTU_MATERIAL_ELASTIC_ORTHOTROPIC_HH__
__BEGIN_AKANTU__
/**
* Orthotropic elastic material
*
* parameters in the material files :
* - n1 : direction of x-axis in material base, normalisation not necessary (default: {1, 0, 0})
* - n2 : direction of y-axis in material base, normalisation not necessary (default: {0, 1, 0})
* - n3 : direction of z-axis in material base, normalisation not necessary (default: {0, 0, 1})
* - rho : density (default: 0)
* - E1 : Young's modulus along n1 (default: 0)
* - E2 : Young's modulus along n2 (default: 0)
* - E3 : Young's modulus along n3 (default: 0)
* - nu12 : Poisson's ratio along 12 (default: 0)
* - nu13 : Poisson's ratio along 13 (default: 0)
* - nu23 : Poisson's ratio along 23 (default: 0)
* - G12 : Shear modulus along 12 (default: 0)
* - G13 : Shear modulus along 13 (default: 0)
* - G23 : Shear modulus along 23 (default: 0)
*/
template<UInt Dim>
class MaterialElasticOrthotropic :
public MaterialElasticLinearAnisotropic<Dim> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialElasticOrthotropic(SolidMechanicsModel & model, const ID & id = "");
~MaterialElasticOrthotropic();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void initMaterial();
virtual void updateInternalParameters();
/// compute the elastic potential energy
virtual void computePotentialEnergy(ElementType el_type,
GhostType ghost_type = _not_ghost);
virtual void computePotentialEnergyByElement(ElementType type, UInt index,
Vector<Real> & epot_on_quad_points);
protected:
inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & sigma,
Real & epot);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(E1, E1, Real);
AKANTU_GET_MACRO(E2, E2, Real);
AKANTU_GET_MACRO(E3, E3, Real);
AKANTU_GET_MACRO(Nu12, nu12, Real);
AKANTU_GET_MACRO(Nu13, nu13, Real);
AKANTU_GET_MACRO(Nu23, nu23, Real);
AKANTU_GET_MACRO(G12, G12, Real);
AKANTU_GET_MACRO(G13, G13, Real);
AKANTU_GET_MACRO(G23, G23, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the n1 young modulus
Real E1;
/// the n2 young modulus
Real E2;
/// the n3 young modulus
Real E3;
/// 12 Poisson coefficient
Real nu12;
/// 13 Poisson coefficient
Real nu13;
/// 23 Poisson coefficient
Real nu23;
/// 12 shear modulus
Real G12;
/// 13 shear modulus
Real G13;
/// 23 shear modulus
Real G23;
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_ELASTIC_ORTHOTROPIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_embedded/embedded_internal_field.hh b/src/model/solid_mechanics/materials/material_embedded/embedded_internal_field.hh
index 33a91e935..b40e84454 100644
--- a/src/model/solid_mechanics/materials/material_embedded/embedded_internal_field.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/embedded_internal_field.hh
@@ -1,82 +1,83 @@
/**
* @file embedded_internal_field.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Thu Mar 19 2015
- * @date last modification: Thu Mar 19 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Jun 30 2015
*
* @brief Embedded Material internal properties
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "internal_field.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_EMBEDDED_INTERNAL_FIELD_HH__
#define __AKANTU_EMBEDDED_INTERNAL_FIELD_HH__
__BEGIN_AKANTU__
class Material;
class FEEngine;
/// This class is used for MaterialReinforcement internal fields
template<typename T>
class EmbeddedInternalField : public InternalField<T> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
/// Constructor
EmbeddedInternalField(const ID & id, Material & material):
InternalField<T>(id,
material,
material.getModel().getFEEngine("EmbeddedInterfaceFEEngine"),
material.getElementFilter()) {
this->spatial_dimension = 1;
}
/// Copy constructor
EmbeddedInternalField(const ID & id, const EmbeddedInternalField & other):
InternalField<T>(id, other) {
this->spatial_dimension = 1;
}
void operator=(const EmbeddedInternalField & other) {
InternalField<T>::operator=(other);
this->spatial_dimension = 1;
}
};
/// Method used to initialise the embedded internal fields from material file
template<>
inline void ParsableParamTyped< EmbeddedInternalField<Real> >::parseParam(const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
Real r = in_param;
param.setDefaultValue(r);
}
__END_AKANTU__
#endif // __AKANTU_EMBEDDED_INTERNAL_FIELD_HH__
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh b/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
index 3c20a1b5e..d00d9f035 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
@@ -1,43 +1,43 @@
/**
* @file material_embedded_includes.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Fri Mar 13 2015
- * @date last modification: Fri Mar 13 2015
+ * @date creation: Fri Jan 04 2013
+ * @date last modification: Fri May 29 2015
*
* @brief List of includes for embedded elements
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_CMAKE_LIST_MATERIALS
# include "material_reinforcement.hh"
# include "material_reinforcement_template.hh"
#endif
#define AKANTU_MATERIAL_REINFORCEMENT_LAW_TMPL_LIST \
((elastic, (MaterialElastic<1>))) \
((plastic, (MaterialLinearIsotropicHardening<1>)))
#define AKANTU_EMBEDDED_MATERIAL_LIST \
((3, (reinforcement, MaterialReinforcementTemplate, \
AKANTU_MATERIAL_REINFORCEMENT_LAW_TMPL_LIST )))
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.cc b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.cc
index bfa8c03a3..77995b69c 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.cc
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.cc
@@ -1,742 +1,742 @@
/**
* @file material_reinforcement.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Thu Mar 12 2015
- * @date last modification: Thu Mar 12 2015
+ * @date creation: Wed Mar 25 2015
+ * @date last modification: Tue Dec 08 2015
*
* @brief Reinforcement material
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_voigthelper.hh"
#include "material_reinforcement.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt dim>
MaterialReinforcement<dim>::MaterialReinforcement(SolidMechanicsModel & model,
UInt spatial_dimension,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id) :
Material(model, dim, mesh, fe_engine, id), // /!\ dim, not spatial_dimension !
model(NULL),
stress_embedded("stress_embedded", *this, 1, fe_engine, this->element_filter),
gradu_embedded("gradu_embedded", *this, 1, fe_engine, this->element_filter),
directing_cosines("directing_cosines", *this, 1, fe_engine, this->element_filter),
pre_stress("pre_stress", *this, 1, fe_engine, this->element_filter),
area(1.0),
shape_derivatives() {
AKANTU_DEBUG_IN();
this->initialize(model);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::initialize(SolidMechanicsModel & a_model) {
this->model = dynamic_cast<EmbeddedInterfaceModel *>(&a_model);
AKANTU_DEBUG_ASSERT(this->model != NULL, "MaterialReinforcement needs an EmbeddedInterfaceModel");
this->registerParam("area", area, _pat_parsable | _pat_modifiable,
"Reinforcement cross-sectional area");
this->registerParam("pre_stress", pre_stress, _pat_parsable | _pat_modifiable,
"Uniform pre-stress");
// Fool the AvgHomogenizingFunctor
//stress.initialize(dim * dim);
// Reallocate the element filter
this->element_filter.free();
this->model->getInterfaceMesh().initElementTypeMapArray(this->element_filter,
1, 1, false, _ek_regular);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
MaterialReinforcement<dim>::~MaterialReinforcement() {
AKANTU_DEBUG_IN();
ElementTypeMap<ElementTypeMapArray<Real> *>::type_iterator it = shape_derivatives.firstType();
ElementTypeMap<ElementTypeMapArray<Real> *>::type_iterator end = shape_derivatives.lastType();
for (; it != end ; ++it) {
delete shape_derivatives(*it, _not_ghost);
delete shape_derivatives(*it, _ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::initMaterial() {
Material::initMaterial();
stress_embedded.initialize(dim * dim);
gradu_embedded.initialize(dim * dim);
pre_stress.initialize(1);
/// We initialise the stuff that is not going to change during the simulation
this->allocBackgroundShapeDerivatives();
this->initBackgroundShapeDerivatives();
this->initDirectingCosines();
}
/* -------------------------------------------------------------------------- */
/**
* Background shape derivatives need to be stored per background element
* types but also per embedded element type, which is why they are stored
* in an ElementTypeMap<ElementTypeMapArray<Real> *>. The outer ElementTypeMap
* refers to the embedded types, and the inner refers to the background types.
*/
template<UInt dim>
void MaterialReinforcement<dim>::allocBackgroundShapeDerivatives() {
AKANTU_DEBUG_IN();
Mesh & interface_mesh = model->getInterfaceMesh();
Mesh & mesh = model->getMesh();
ghost_type_t::iterator int_ghost_it = ghost_type_t::begin();
// Loop over interface ghosts
for (; int_ghost_it != ghost_type_t::end() ; ++int_ghost_it) {
Mesh::type_iterator interface_type_it = interface_mesh.firstType(1, *int_ghost_it);
Mesh::type_iterator interface_type_end = interface_mesh.lastType(1, *int_ghost_it);
// Loop over interface types
for (; interface_type_it != interface_type_end ; ++interface_type_it) {
Mesh::type_iterator background_type_it = mesh.firstType(dim, *int_ghost_it);
Mesh::type_iterator background_type_end = mesh.lastType(dim, *int_ghost_it);
// Loop over background types
for (; background_type_it != background_type_end ; ++background_type_it) {
const ElementType & int_type = *interface_type_it;
const ElementType & back_type = *background_type_it;
const GhostType & int_ghost = *int_ghost_it;
std::string shaped_id = "embedded_shape_derivatives";
if (int_ghost == _ghost) shaped_id += ":ghost";
ElementTypeMapArray<Real> * shaped_etma = new ElementTypeMapArray<Real>(shaped_id, this->name);
UInt nb_points = Mesh::getNbNodesPerElement(back_type);
UInt nb_quad_points = model->getFEEngine("EmbeddedInterfaceFEEngine").getNbIntegrationPoints(int_type);
UInt nb_elements = element_filter(int_type, int_ghost).getSize();
// Alloc the background ElementTypeMapArray
shaped_etma->alloc(nb_elements * nb_quad_points,
dim * nb_points,
back_type);
// Insert the background ElementTypeMapArray in the interface ElementTypeMap
shape_derivatives(shaped_etma, int_type, int_ghost);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::initBackgroundShapeDerivatives() {
AKANTU_DEBUG_IN();
Mesh & mesh = model->getMesh();
Mesh::type_iterator type_it = mesh.firstType(dim, _not_ghost);
Mesh::type_iterator type_end = mesh.lastType(dim, _not_ghost);
for (; type_it != type_end ; ++type_it) {
computeBackgroundShapeDerivatives(*type_it, _not_ghost);
//computeBackgroundShapeDerivatives(*type_it, _ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::initDirectingCosines() {
AKANTU_DEBUG_IN();
Mesh & mesh = model->getInterfaceMesh();
Mesh::type_iterator type_it = mesh.firstType(1, _not_ghost);
Mesh::type_iterator type_end = mesh.lastType(1, _not_ghost);
const UInt voigt_size = getTangentStiffnessVoigtSize(dim);
directing_cosines.initialize(voigt_size * voigt_size);
for (; type_it != type_end ; ++type_it) {
computeDirectingCosines(*type_it, _not_ghost);
//computeDirectingCosines(*type_it, _ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::assembleStiffnessMatrix(GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & interface_mesh = model->getInterfaceMesh();
Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
for (; type_it != type_end ; ++type_it) {
assembleStiffnessMatrix(*type_it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::updateResidual(GhostType ghost_type) {
AKANTU_DEBUG_IN();
computeAllStresses(ghost_type);
assembleResidual(ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::assembleResidual(GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & interface_mesh = model->getInterfaceMesh();
Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
for (; type_it != type_end ; ++type_it) {
assembleResidual(*type_it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::computeGradU(const ElementType & type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<UInt> & elem_filter = element_filter(type, ghost_type);
UInt nb_element = elem_filter.getSize();
UInt nb_quad_points = model->getFEEngine("EmbeddedInterfaceFEEngine").getNbIntegrationPoints(type);
Array<Real> & gradu_vec = gradu_embedded(type, ghost_type);
Mesh::type_iterator back_it = model->getMesh().firstType(dim, ghost_type);
Mesh::type_iterator back_end = model->getMesh().lastType(dim, ghost_type);
for (; back_it != back_end ; ++back_it) {
UInt nodes_per_background_e = Mesh::getNbNodesPerElement(*back_it);
Array<Real> & shapesd = shape_derivatives(type, ghost_type)->operator()(*back_it, ghost_type);
Array<UInt> * background_filter = new Array<UInt>(nb_element, 1, "background_filter");
filterInterfaceBackgroundElements(*background_filter, *back_it, type, ghost_type);
Array<Real> * disp_per_element = new Array<Real>(0, dim * nodes_per_background_e, "disp_elem");
FEEngine::extractNodalToElementField(model->getMesh(),
model->getDisplacement(),
*disp_per_element,
*back_it, ghost_type, *background_filter);
Array<Real>::matrix_iterator disp_it = disp_per_element->begin(dim, nodes_per_background_e);
Array<Real>::matrix_iterator disp_end = disp_per_element->end(dim, nodes_per_background_e);
Array<Real>::matrix_iterator shapes_it = shapesd.begin(dim, nodes_per_background_e);
Array<Real>::matrix_iterator grad_u_it = gradu_vec.begin(dim, dim);
for (; disp_it != disp_end ; ++disp_it) {
for (UInt i = 0; i < nb_quad_points; i++, ++shapes_it, ++grad_u_it) {
Matrix<Real> & B = *shapes_it;
Matrix<Real> & du = *grad_u_it;
Matrix<Real> & u = *disp_it;
du.mul<false, true>(u, B);
}
}
delete background_filter;
delete disp_per_element;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::computeAllStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = model->getInterfaceMesh().firstType();
Mesh::type_iterator last_type = model->getInterfaceMesh().lastType();
for(; it != last_type; ++it) {
computeGradU(*it, ghost_type);
computeStress(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::assembleResidual(const ElementType & type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & mesh = model->getMesh();
Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
for (; type_it != type_end ; ++type_it) {
assembleResidualInterface(type, *type_it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Computes and assemble the residual. Residual in reinforcement is computed as :
* \f[
* \vec{r} = A_s \int_S{\mathbf{B}^T\mathbf{C}^T \vec{\sigma_s}\,\mathrm{d}s}
* \f]
*/
template<UInt dim>
void MaterialReinforcement<dim>::assembleResidualInterface(const ElementType & interface_type,
const ElementType & background_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt voigt_size = getTangentStiffnessVoigtSize(dim);
Array<Real> & residual = const_cast<Array<Real> &>(model->getResidual());
FEEngine & interface_engine = model->getFEEngine("EmbeddedInterfaceFEEngine");
FEEngine & background_engine = model->getFEEngine();
Array<UInt> & elem_filter = element_filter(interface_type, ghost_type);
UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
UInt nb_quadrature_points = interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
UInt nb_element = elem_filter.getSize();
UInt back_dof = dim * nodes_per_background_e;
Array<Real> & shapesd = shape_derivatives(interface_type, ghost_type)->operator()(background_type, ghost_type);
Array<Real> * integrant = new Array<Real>(nb_quadrature_points * nb_element,
back_dof,
"integrant");
Array<Real>::vector_iterator integrant_it =
integrant->begin(back_dof);
Array<Real>::vector_iterator integrant_end =
integrant->end(back_dof);
Array<Real>::matrix_iterator B_it =
shapesd.begin(dim, nodes_per_background_e);
Array<Real>::matrix_iterator C_it =
directing_cosines(interface_type, ghost_type).begin(voigt_size, voigt_size);
Array<Real>::matrix_iterator sigma_it =
stress_embedded(interface_type, ghost_type).begin(dim, dim);
Vector<Real> sigma(voigt_size);
Matrix<Real> Bvoigt(voigt_size, back_dof);
Vector<Real> Ct_sigma(voigt_size);
for (; integrant_it != integrant_end ; ++integrant_it,
++B_it,
++C_it,
++sigma_it) {
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*B_it, Bvoigt, nodes_per_background_e);
Matrix<Real> & C = *C_it;
Vector<Real> & BtCt_sigma = *integrant_it;
stressTensorToVoigtVector(*sigma_it, sigma);
Ct_sigma.mul<true>(C, sigma);
BtCt_sigma.mul<true>(Bvoigt, Ct_sigma);
BtCt_sigma *= area;
}
Array<Real> * residual_interface = new Array<Real>(nb_element, back_dof, "residual_interface");
interface_engine.integrate(*integrant,
*residual_interface,
back_dof,
interface_type, ghost_type,
elem_filter);
delete integrant;
Array<UInt> * background_filter = new Array<UInt>(nb_element, 1, "background_filter");
filterInterfaceBackgroundElements(*background_filter,
background_type, interface_type,
ghost_type);
background_engine.assembleArray(*residual_interface, residual,
model->getDOFSynchronizer().getLocalDOFEquationNumbers(),
dim, background_type, ghost_type, *background_filter, -1.0);
delete residual_interface;
delete background_filter;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::filterInterfaceBackgroundElements(Array<UInt> & filter,
const ElementType & type,
const ElementType & interface_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
filter.resize(0);
filter.clear();
Array<Element> & elements = model->getInterfaceAssociatedElements(interface_type, ghost_type);
Array<UInt> & elem_filter = element_filter(interface_type, ghost_type);
Array<UInt>::scalar_iterator
filter_it = elem_filter.begin(),
filter_end = elem_filter.end();
for (; filter_it != filter_end ; ++filter_it) {
Element & elem = elements(*filter_it);
if (elem.type == type) filter.push_back(elem.element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::computeDirectingCosines(const ElementType & type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & interface_mesh = this->model->getInterfaceMesh();
const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const UInt steel_dof = dim * nb_nodes_per_element;
const UInt voigt_size = getTangentStiffnessVoigtSize(dim);
const UInt nb_quad_points =
model->getFEEngine("EmbeddedInterfaceFEEngine").getNbIntegrationPoints(type, ghost_type);
Array<Real> node_coordinates(this->element_filter(type, ghost_type).getSize(), steel_dof);
this->model->getFEEngine().template extractNodalToElementField<Real>(interface_mesh,
interface_mesh.getNodes(),
node_coordinates,
type,
ghost_type,
this->element_filter(type, ghost_type));
Array<Real>::matrix_iterator
directing_cosines_it = directing_cosines(type, ghost_type).begin(voigt_size, voigt_size);
Array<Real>::matrix_iterator node_coordinates_it = node_coordinates.begin(dim, nb_nodes_per_element);
Array<Real>::matrix_iterator node_coordinates_end = node_coordinates.end(dim, nb_nodes_per_element);
for (; node_coordinates_it != node_coordinates_end ; ++node_coordinates_it) {
for (UInt i = 0 ; i < nb_quad_points ; i++, ++directing_cosines_it) {
Matrix<Real> & nodes = *node_coordinates_it;
Matrix<Real> & cosines = *directing_cosines_it;
computeDirectingCosinesOnQuad(nodes, cosines);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialReinforcement<dim>::assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & mesh = model->getMesh();
Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
for (; type_it != type_end ; ++type_it) {
assembleStiffnessMatrixInterface(type, *type_it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Computes the reinforcement stiffness matrix (Gomes & Awruch, 2001)
* \f[
* \mathbf{K}_e = \sum_{i=1}^R{A_i\int_{S_i}{\mathbf{B}^T
* \mathbf{C}_i^T \mathbf{D}_{s, i} \mathbf{C}_i \mathbf{B}\,\mathrm{d}s}}
* \f]
*/
template<UInt dim>
void MaterialReinforcement<dim>::assembleStiffnessMatrixInterface(const ElementType & interface_type,
const ElementType & background_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt voigt_size = getTangentStiffnessVoigtSize(dim);
SparseMatrix & K = const_cast<SparseMatrix &>(model->getStiffnessMatrix());
FEEngine & background_engine = model->getFEEngine();
FEEngine & interface_engine = model->getFEEngine("EmbeddedInterfaceFEEngine");
Array<UInt> & elem_filter = element_filter(interface_type, ghost_type);
Array<Real> & grad_u = gradu_embedded(interface_type, ghost_type);
UInt nb_element = elem_filter.getSize();
UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
UInt nb_quadrature_points = interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
UInt back_dof = dim * nodes_per_background_e;
UInt integrant_size = back_dof;
grad_u.resize(nb_quadrature_points * nb_element);
Array<Real> * tangent_moduli = new Array<Real>(nb_element * nb_quadrature_points,
1, "interface_tangent_moduli");
tangent_moduli->clear();
computeTangentModuli(interface_type, *tangent_moduli, ghost_type);
Array<Real> & shapesd = shape_derivatives(interface_type, ghost_type)->operator()(background_type, ghost_type);
Array<Real> * integrant = new Array<Real>(nb_element * nb_quadrature_points,
integrant_size * integrant_size,
"B^t*C^t*D*C*B");
integrant->clear();
/// Temporary matrices for integrant product
Matrix<Real> Bvoigt(voigt_size, back_dof);
Matrix<Real> DC(voigt_size, voigt_size);
Matrix<Real> DCB(voigt_size, back_dof);
Matrix<Real> CtDCB(voigt_size, back_dof);
Array<Real>::scalar_iterator D_it = tangent_moduli->begin();
Array<Real>::scalar_iterator D_end = tangent_moduli->end();
Array<Real>::matrix_iterator C_it =
directing_cosines(interface_type, ghost_type).begin(voigt_size, voigt_size);
Array<Real>::matrix_iterator B_it =
shapesd.begin(dim, nodes_per_background_e);
Array<Real>::matrix_iterator integrant_it =
integrant->begin(integrant_size, integrant_size);
for (; D_it != D_end ; ++D_it, ++C_it, ++B_it, ++integrant_it) {
Real & D = *D_it;
Matrix<Real> & C = *C_it;
Matrix<Real> & B = *B_it;
Matrix<Real> & BtCtDCB = *integrant_it;
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(B, Bvoigt, nodes_per_background_e);
DC.clear();
DC(0, 0) = D * area;
DC *= C;
DCB.mul<false, false>(DC, Bvoigt);
CtDCB.mul<true, false>(C, DCB);
BtCtDCB.mul<true, false>(Bvoigt, CtDCB);
}
delete tangent_moduli;
Array<Real> * K_interface = new Array<Real>(nb_element, integrant_size * integrant_size, "K_interface");
interface_engine.integrate(*integrant, *K_interface,
integrant_size * integrant_size,
interface_type, ghost_type,
elem_filter);
delete integrant;
Array<UInt> * background_filter = new Array<UInt>(nb_element, 1, "background_filter");
filterInterfaceBackgroundElements(*background_filter,
background_type, interface_type,
ghost_type);
background_engine.assembleMatrix(*K_interface, K, dim, background_type, ghost_type, *background_filter);
delete K_interface;
delete background_filter;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/// In this function, type and ghost_type refer to background elements
template<UInt dim>
void MaterialReinforcement<dim>::computeBackgroundShapeDerivatives(const ElementType & type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & interface_mesh = model->getInterfaceMesh();
FEEngine & engine = model->getFEEngine();
FEEngine & interface_engine = model->getFEEngine("EmbeddedInterfaceFEEngine");
Mesh::type_iterator interface_type = interface_mesh.firstType();
Mesh::type_iterator interface_last = interface_mesh.lastType();
for (; interface_type != interface_last ; ++interface_type) {
Array<UInt> & filter = element_filter(*interface_type, ghost_type);
const UInt nb_elements = filter.getSize();
const UInt nb_nodes = Mesh::getNbNodesPerElement(type);
const UInt nb_quad_per_element = interface_engine.getNbIntegrationPoints(*interface_type);
Array<Real> quad_pos(nb_quad_per_element * nb_elements, dim, "interface_quad_points");
quad_pos.resize(nb_quad_per_element * nb_elements);
interface_engine.interpolateOnIntegrationPoints(interface_mesh.getNodes(),
quad_pos, dim, *interface_type,
ghost_type, filter);
Array<Real> & background_shapesd = shape_derivatives(*interface_type, ghost_type)->operator()(type, ghost_type);
background_shapesd.clear();
Array<UInt> * background_elements = new Array<UInt>(nb_elements, 1, "computeBackgroundShapeDerivatives:background_filter");
filterInterfaceBackgroundElements(*background_elements, type, *interface_type, ghost_type);
Array<UInt>::scalar_iterator
back_it = background_elements->begin(),
back_end = background_elements->end();
Array<Real>::matrix_iterator shapesd_it = background_shapesd.begin(dim, nb_nodes);
Array<Real>::vector_iterator quad_pos_it = quad_pos.begin(dim);
for (; back_it != back_end ; ++back_it) {
for (UInt i = 0 ; i < nb_quad_per_element ; i++, ++shapesd_it, ++quad_pos_it)
engine.computeShapeDerivatives(*quad_pos_it, *back_it, type, *shapesd_it, ghost_type);
}
delete background_elements;
}
AKANTU_DEBUG_OUT();
}
template<UInt dim>
Real MaterialReinforcement<dim>::getEnergy(std::string id) {
AKANTU_DEBUG_IN();
if (id == "potential") {
Real epot = 0.;
computePotentialEnergyByElements();
Mesh::type_iterator
it = element_filter.firstType(spatial_dimension),
end = element_filter.lastType(spatial_dimension);
for (; it != end ; ++it) {
FEEngine & interface_engine = model->getFEEngine("EmbeddedInterfaceFEEngine");
epot += interface_engine.integrate(potential_energy(*it, _not_ghost),
*it, _not_ghost,
element_filter(*it, _not_ghost));
epot *= area;
}
return epot;
}
AKANTU_DEBUG_OUT();
return 0;
}
// /* -------------------------------------------------------------------------- */
// template<UInt dim>
// ElementTypeMap<UInt> MaterialReinforcement<dim>::getInternalDataPerElem(const ID & field_name,
// const ElementKind & kind,
// const ID & fe_engine_id) const {
// return Material::getInternalDataPerElem(field_name, kind, "EmbeddedInterfaceFEEngine");
// }
// /* -------------------------------------------------------------------------- */
// // Author is Guillaume Anciaux, see material.cc
// template<UInt dim>
// void MaterialReinforcement<dim>::flattenInternal(const std::string & field_id,
// ElementTypeMapArray<Real> & internal_flat,
// const GhostType ghost_type,
// ElementKind element_kind) const {
// AKANTU_DEBUG_IN();
// if (field_id == "stress_embedded" || field_id == "inelastic_strain") {
// Material::flattenInternalIntern(field_id,
// internal_flat,
// 1,
// ghost_type,
// _ek_not_defined,
// &(this->element_filter),
// &(this->model->getInterfaceMesh()));
// }
// AKANTU_DEBUG_OUT();
// }
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialReinforcement);
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
index 1969cd56f..b38d9c21a 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
@@ -1,197 +1,197 @@
/**
* @file material_reinforcement.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Thu Mar 12 2015
- * @date last modification: Thu Mar 12 2015
+ * @date creation: Fri Mar 13 2015
+ * @date last modification: Tue Nov 24 2015
*
* @brief Reinforcement material
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_REINFORCEMENT_HH__
#define __AKANTU_MATERIAL_REINFORCEMENT_HH__
#include "aka_common.hh"
#include "material.hh"
#include "embedded_interface_model.hh"
#include "embedded_internal_field.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
* @brief Material used to represent embedded reinforcements
*
* This class is used for computing the reinforcement stiffness matrix
* along with the reinforcement residual. Room is made for constitutive law,
* but actual use of contitutive laws is made in MaterialReinforcementTemplate.
*
* Be careful with the dimensions in this class :
* - this->spatial_dimension is always 1
* - the template parameter dim is the dimension of the problem
*/
template<UInt dim>
class MaterialReinforcement : virtual public Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
/// Constructor
MaterialReinforcement(SolidMechanicsModel & model,
UInt spatial_dimension,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id = "");
/// Destructor
virtual ~MaterialReinforcement();
protected:
void initialize(SolidMechanicsModel & a_model);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// Init the material
virtual void initMaterial();
/// Init the background shape derivatives
void initBackgroundShapeDerivatives();
/// Init the cosine matrices
void initDirectingCosines();
/// Assemble stiffness matrix
virtual void assembleStiffnessMatrix(GhostType ghost_type);
/// Update the residual
virtual void updateResidual(GhostType ghost_type = _not_ghost);
/// Assembled the residual
virtual void assembleResidual(GhostType ghost_type);
/// Compute all the stresses !
virtual void computeAllStresses(GhostType ghost_type);
/// Compute the stiffness parameter for elements of a type
virtual void computeTangentModuli(const ElementType & type,
Array<Real> & tangent,
GhostType ghost_type) = 0;
/// Compute energy
virtual Real getEnergy(std::string id);
// virtual ElementTypeMap<UInt> getInternalDataPerElem(const ID & field_name,
// const ElementKind & kind,
// const ID & fe_engine_id) const;
// /// Reimplementation of Material's function to accomodate for interface mesh
// virtual void flattenInternal(const std::string & field_id,
// ElementTypeMapArray<Real> & internal_flat,
// const GhostType ghost_type = _not_ghost,
// ElementKind element_kind = _ek_not_defined) const;
/* ------------------------------------------------------------------------ */
/* Protected methods */
/* ------------------------------------------------------------------------ */
protected:
/// Allocate the background shape derivatives
void allocBackgroundShapeDerivatives();
/// Compute the directing cosines matrix for one element type
void computeDirectingCosines(const ElementType & type, GhostType ghost_type);
/// Compute the directing cosines matrix on quadrature points.
inline void computeDirectingCosinesOnQuad(const Matrix<Real> & nodes,
Matrix<Real> & cosines);
/// Assemble the stiffness matrix for an element type (typically _segment_2)
void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type);
/// Assemble the stiffness matrix for background & interface types
void assembleStiffnessMatrixInterface(const ElementType & interface_type,
const ElementType & background_type,
GhostType ghost_type);
/// Compute the background shape derivatives for a type
void computeBackgroundShapeDerivatives(const ElementType & type, GhostType ghost_type);
/// Filter elements crossed by interface of a type
void filterInterfaceBackgroundElements(Array<UInt> & filter,
const ElementType & type,
const ElementType & interface_type,
GhostType ghost_type);
/// Assemble the residual of one type of element (typically _segment_2)
void assembleResidual(const ElementType & type, GhostType ghost_type);
/// Assemble the residual for a pair of elements
void assembleResidualInterface(const ElementType & interface_type,
const ElementType & background_type,
GhostType ghost_type);
// TODO figure out why voigt size is 4 in 2D
inline void stressTensorToVoigtVector(const Matrix<Real> & tensor, Vector<Real> & vector);
inline void strainTensorToVoigtVector(const Matrix<Real> & tensor, Vector<Real> & vector);
/// Compute gradu on the interface quadrature points
virtual void computeGradU(const ElementType & type, GhostType ghost_type);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Embedded model
EmbeddedInterfaceModel * model;
/// Stress in the reinforcement
InternalField<Real> stress_embedded;
/// Gradu of concrete on reinforcement
InternalField<Real> gradu_embedded;
/// C matrix on quad
InternalField<Real> directing_cosines;
/// Prestress on quad
InternalField<Real> pre_stress;
/// Cross-sectional area
Real area;
/// Background mesh shape derivatives
ElementTypeMap< ElementTypeMapArray<Real> * > shape_derivatives;
};
#include "material_reinforcement_inline_impl.cc"
__END_AKANTU__
#endif // __AKANTU_MATERIAL_REINFORCEMENT_HH__
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_inline_impl.cc b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_inline_impl.cc
index ec0b8e06f..cf23faf42 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_inline_impl.cc
@@ -1,123 +1,124 @@
/**
* @file material_reinforcement_inline_impl.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Thu Mar 12 2015
- * @date last modification: Thu Mar 12 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Jul 14 2015
*
* @brief Reinforcement material
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/**
* The structure of the directing cosines matrix is :
* \f{eqnarray*}{
* C_{1,\cdot} & = & (l^2, m^2, n^2, mn, ln, lm) \\
* C_{i,j} & = & 0
* \f}
*
* with :
* \f[
* (l, m, n) = \frac{1}{\|\frac{\mathrm{d}\vec{r}(s)}{\mathrm{d}s}\|} \cdot \frac{\mathrm{d}\vec{r}(s)}{\mathrm{d}s}
* \f]
*/
template<UInt dim>
inline void MaterialReinforcement<dim>::computeDirectingCosinesOnQuad(const Matrix<Real> & nodes,
Matrix<Real> & cosines) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(nodes.cols() == 2, "Higher order reinforcement elements not implemented");
const Vector<Real> & a = nodes(0), b = nodes(1);
Vector<Real> delta = b - a;
cosines.clear();
Real sq_length = 0.;
for (UInt i = 0 ; i < dim ; i++) {
sq_length += Math::pow<2, Real>(delta(i));
}
if (dim == 2) {
cosines(0, 0) = Math::pow<2, Real>(delta(0)); // l^2
cosines(0, 1) = Math::pow<2, Real>(delta(1)); // m^2
cosines(0, 2) = delta(0) * delta(1); // lm
} else if (dim == 3) {
cosines(0, 0) = Math::pow<2, Real>(delta(0)); // l^2
cosines(0, 1) = Math::pow<2, Real>(delta(1)); // m^2
cosines(0, 2) = Math::pow<2, Real>(delta(2)); // n^2
cosines(0, 3) = delta(1) * delta(2); // mn
cosines(0, 4) = delta(0) * delta(2); // ln
cosines(0, 5) = delta(0) * delta(1); // lm
}
cosines /= sq_length;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialReinforcement<dim>::stressTensorToVoigtVector(const Matrix<Real> & tensor,
Vector<Real> & vector) {
AKANTU_DEBUG_IN();
for (UInt i = 0; i < dim; i++) {
vector(i) = tensor(i, i);
}
if (dim == 2) {
vector(2) = tensor(0, 1);
} else if (dim == 3) {
vector(3) = tensor(1, 2);
vector(4) = tensor(0, 2);
vector(5) = tensor(0, 1);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialReinforcement<dim>::strainTensorToVoigtVector(const Matrix<Real> & tensor,
Vector<Real> & vector) {
AKANTU_DEBUG_IN();
for (UInt i = 0; i < dim; i++) {
vector(i) = tensor(i, i);
}
if (dim == 2) {
vector(2) = 2 * tensor(0, 1);
} else if (dim == 3) {
vector(3) = 2 * tensor(1, 2);
vector(4) = 2 * tensor(0, 2);
vector(5) = 2 * tensor(0, 1);
}
AKANTU_DEBUG_OUT();
}
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template.hh b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template.hh
index b62de7c69..2a6e23721 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template.hh
@@ -1,109 +1,109 @@
/**
* @file material_reinforcement_template.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Mon Mar 16 2015
- * @date last modification: Mon Mar 16 2015
+ * @date creation: Wed Mar 25 2015
+ * @date last modification: Mon Jun 01 2015
*
* @brief Reinforcement material templated with constitutive law
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_REINFORCEMENT_TEMPLATE_HH__
#define __AKANTU_MATERIAL_REINFORCEMENT_TEMPLATE_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material_reinforcement.hh"
#include "material_elastic.hh"
#include "material_linear_isotropic_hardening.hh"
__BEGIN_AKANTU__
/**
* @brief Implementation of MaterialReinforcement with 1D constitutive law
* @see MaterialReinforcement, MaterialElastic
*
* This class is a reinforcement featuring a constitutive law.
* <strong>Be careful !</strong> Because of multiple inheritance, this class
* forms a diamond.
*/
template<UInt dim, class ConstLaw = MaterialElastic<1> >
class MaterialReinforcementTemplate : public MaterialReinforcement<dim>,
public ConstLaw {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
/// Constructor
MaterialReinforcementTemplate(SolidMechanicsModel & a_model, const ID & id = "");
/// Destructor
virtual ~MaterialReinforcementTemplate();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// Initialises the material
void initMaterial();
/// Compute the stiffness parameter for elements of a type
virtual void computeTangentModuli(const ElementType & type,
Array<Real> & tangent,
GhostType ghost_type);
/// Computes stress used by constitutive law
virtual void computeStress(ElementType type, GhostType ghost_type);
/// Computes gradu to be used by the constitutive law
virtual void computeGradU(const ElementType & type, GhostType ghost_type);
/// Compute the potential energy of the reinforcement
virtual void computePotentialEnergy(ElementType type, GhostType ghost_type = _not_ghost);
/// Get energy in reinforcement (currently limited to potential)
virtual Real getEnergy(std::string id);
protected:
/**
* @brief Compute interface gradu from bulk gradu
* \f[
* \varepsilon_s = C \varepsilon_c
* \f]
*/
inline void computeInterfaceGradUOnQuad(const Matrix<Real> & full_gradu,
Real & gradu,
const Matrix<Real> & C);
};
#include "material_reinforcement_template_tmpl.hh"
__END_AKANTU__
#endif // __AKANTU_MATERIAL_REINFORCEMENT_TEMPLATE_HH__
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template_tmpl.hh b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template_tmpl.hh
index a458c76bf..0a5ff381b 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template_tmpl.hh
@@ -1,182 +1,182 @@
/**
* @file material_reinforcement_template_tmpl.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Mon Mar 16 2015
- * @date last modification: Mon Mar 16 2015
+ * @date creation: Wed Mar 25 2015
+ * @date last modification: Thu Oct 15 2015
*
* @brief Reinforcement material templated with constitutive law
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
// /!\ no namespace here !
/* -------------------------------------------------------------------------- */
template<UInt dim, class ConstLaw>
MaterialReinforcementTemplate<dim, ConstLaw>::MaterialReinforcementTemplate(SolidMechanicsModel & a_model,
const ID & id):
Material(a_model, 1,
dynamic_cast<EmbeddedInterfaceModel &>(a_model).getInterfaceMesh(),
a_model.getFEEngine("EmbeddedInterfaceFEEngine"), id),
MaterialReinforcement<dim>(a_model, 1,
dynamic_cast<EmbeddedInterfaceModel &>(a_model).getInterfaceMesh(),
a_model.getFEEngine("EmbeddedInterfaceFEEngine"), id),
ConstLaw(a_model, 1,
dynamic_cast<EmbeddedInterfaceModel &>(a_model).getInterfaceMesh(),
a_model.getFEEngine("EmbeddedInterfaceFEEngine"), id)
{}
/* -------------------------------------------------------------------------- */
template<UInt dim, class ConstLaw>
MaterialReinforcementTemplate<dim, ConstLaw>::~MaterialReinforcementTemplate()
{}
/* -------------------------------------------------------------------------- */
template<UInt dim, class ConstLaw>
void MaterialReinforcementTemplate<dim, ConstLaw>::initMaterial() {
MaterialReinforcement<dim>::initMaterial();
ConstLaw::initMaterial();
// Needed for plasticity law
this->ConstLaw::nu = 0.5;
this->ConstLaw::updateInternalParameters();
}
/* -------------------------------------------------------------------------- */
template<UInt dim, class ConstLaw>
void MaterialReinforcementTemplate<dim, ConstLaw>::computeGradU(const ElementType & el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialReinforcement<dim>::computeGradU(el_type, ghost_type);
const UInt voigt_size = Material::getTangentStiffnessVoigtSize(dim);
Array<Real>::matrix_iterator full_gradu_it =
this->MaterialReinforcement<dim>::gradu_embedded(el_type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator full_gradu_end =
this->MaterialReinforcement<dim>::gradu_embedded(el_type, ghost_type).end(dim, dim);
Array<Real>::scalar_iterator gradu_it =
this->ConstLaw::gradu(el_type, ghost_type).begin();
Array<Real>::matrix_iterator cosines_it =
this->directing_cosines(el_type, ghost_type).begin(voigt_size, voigt_size);
for (; full_gradu_it != full_gradu_end ; ++full_gradu_it,
++gradu_it,
++cosines_it) {
Matrix<Real> & full_gradu = *full_gradu_it;
Real & gradu = *gradu_it;
Matrix<Real> & C = *cosines_it;
computeInterfaceGradUOnQuad(full_gradu, gradu, C);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim, class ConstLaw>
void MaterialReinforcementTemplate<dim, ConstLaw>::computeInterfaceGradUOnQuad(const Matrix<Real> & full_gradu,
Real & gradu,
const Matrix<Real> & C) {
const UInt voigt_size = Material::getTangentStiffnessVoigtSize(dim);
Matrix<Real> epsilon(dim, dim);
Vector<Real> e_voigt(voigt_size);
Vector<Real> e_interface_voigt(voigt_size);
epsilon = 0.5 * (full_gradu + full_gradu.transpose());
MaterialReinforcement<dim>::strainTensorToVoigtVector(epsilon, e_voigt);
e_interface_voigt.mul<false>(C, e_voigt);
gradu = e_interface_voigt(0);
}
/* -------------------------------------------------------------------------- */
template<UInt dim, class ConstLaw>
void MaterialReinforcementTemplate<dim, ConstLaw>::computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(tangent.getNbComponent() == 1, "Reinforcements only work in 1D");
ConstLaw::computeTangentModuli(el_type, tangent, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim, class ConstLaw>
void MaterialReinforcementTemplate<dim, ConstLaw>::computeStress(ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
ConstLaw::computeStress(type, ghost_type);
Array<Real>::matrix_iterator full_sigma_it =
this->MaterialReinforcement<dim>::stress_embedded(type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator full_sigma_end =
this->MaterialReinforcement<dim>::stress_embedded(type, ghost_type).end(dim, dim);
Array<Real>::scalar_iterator sigma_it =
this->ConstLaw::stress(type, ghost_type).begin();
Array<Real>::scalar_iterator pre_stress_it =
this->MaterialReinforcement<dim>::pre_stress(type, ghost_type).begin();
for (; full_sigma_it != full_sigma_end ; ++full_sigma_it, ++sigma_it, ++pre_stress_it) {
Matrix<Real> & sigma = *full_sigma_it;
sigma(0, 0) = *sigma_it + *pre_stress_it;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim, class ConstLaw>
Real MaterialReinforcementTemplate<dim, ConstLaw>::getEnergy(std::string id) {
return MaterialReinforcement<dim>::getEnergy(id);
}
/* -------------------------------------------------------------------------- */
template <UInt dim, class ConstLaw>
void MaterialReinforcementTemplate<dim, ConstLaw>::computePotentialEnergy(ElementType type,
GhostType ghost_type) {
const UInt nb_elements = this->element_filter(type, ghost_type).getSize();
const UInt nb_quad = this->model->getFEEngine("EmbeddedInterfaceFEEngine").getNbIntegrationPoints(type);
this->ConstLaw::potential_energy.alloc(nb_quad * nb_elements, 1, type, ghost_type, 0.);
ConstLaw::computePotentialEnergy(type, ghost_type);
}
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
index 919eaf50f..59916e22f 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
@@ -1,271 +1,271 @@
/**
* @file material_neohookean.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Mon Apr 08 2013
- * @date last modification: Tue Sep 16 2014
+ * @date last modification: Tue Aug 04 2015
*
* @brief Specialization of the material class for finite deformation neo-hookean material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_neohookean.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialNeohookean<spatial_dimension>::MaterialNeohookean(SolidMechanicsModel & model, const ID & id) :
PlaneStressToolbox<spatial_dimension>(model, id) {
AKANTU_DEBUG_IN();
this->registerParam( "E", E, Real( 0.), _pat_parsable | _pat_modifiable, "Young's modulus");
this->registerParam( "nu", nu, Real(0.5), _pat_parsable | _pat_modifiable, "Poisson's ratio");
this->registerParam("lambda", lambda, _pat_readable, "First Lamé coefficient");
this->registerParam( "mu", mu, _pat_readable, "Second Lamé coefficient");
this->registerParam( "kapa", kpa, _pat_readable, "Bulk coefficient");
this->finite_deformation = true;
this->initialize_third_axis_deformation = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNeohookean<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
PlaneStressToolbox<spatial_dimension>::initMaterial();
if (spatial_dimension == 1) nu = 0.;
this->updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<> void MaterialNeohookean<2>::initMaterial() {
AKANTU_DEBUG_IN();
PlaneStressToolbox<2>::initMaterial();
this->updateInternalParameters();
if(this->plane_stress) this->third_axis_deformation.setDefaultValue(1.);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNeohookean<spatial_dimension>::updateInternalParameters() {
lambda = nu * E / ((1 + nu) * (1 - 2 * nu));
mu = E / (2 * (1 + nu));
kpa = lambda + 2. / 3. * mu;
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialNeohookean<dim>::computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
PlaneStressToolbox<dim>::computeCauchyStressPlaneStress(el_type, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialNeohookean<2>::computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::matrix_iterator gradu_it =
this->gradu(el_type, ghost_type).begin(2, 2);
Array<Real>::matrix_iterator gradu_end =
this->gradu(el_type, ghost_type).end(2, 2);
Array<Real>::matrix_iterator piola_it =
this->piola_kirchhoff_2(el_type, ghost_type).begin(2, 2);
Array<Real>::matrix_iterator stress_it =
this->stress(el_type, ghost_type).begin(2, 2);
Array<Real>::const_scalar_iterator c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
Matrix<Real> F_tensor(2, 2);
for (; gradu_it != gradu_end; ++gradu_it, ++piola_it, ++stress_it, ++c33_it) {
Matrix<Real> & grad_u = *gradu_it;
Matrix<Real> & piola = *piola_it;
Matrix<Real> & sigma = *stress_it;
gradUToF<2 > (grad_u, F_tensor);
computeCauchyStressOnQuad<2 >(F_tensor, piola, sigma, *c33_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialNeohookean<dim>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeStressOnQuad(grad_u, sigma);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialNeohookean<2>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
if(this->plane_stress){
PlaneStressToolbox<2>::computeStress(el_type, ghost_type);
Array<Real>::const_scalar_iterator c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeStressOnQuad(grad_u, sigma, *c33_it);
++c33_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
else{
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeStressOnQuad(grad_u, sigma);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialNeohookean<dim>::computeThirdAxisDeformation(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialNeohookean<2>::computeThirdAxisDeformation(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(this->plane_stress, "The third component of the strain can only be computed for 2D problems in Plane Stress!!");
Array<Real>::scalar_iterator c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeThirdAxisDeformationOnQuad(grad_u, *c33_it);
++c33_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNeohookean<spatial_dimension>::computePotentialEnergy(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Material::computePotentialEnergy(el_type, ghost_type);
if(ghost_type != _not_ghost) return;
Array<Real>::scalar_iterator epot = this->potential_energy(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computePotentialEnergyOnQuad(grad_u, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNeohookean<spatial_dimension>::computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
Array<Real> & tangent_matrix,
__attribute__((unused)) GhostType ghost_type) {
AKANTU_DEBUG_IN();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
computeTangentModuliOnQuad(tangent, grad_u);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialNeohookean<2>::computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
Array<Real> & tangent_matrix,
__attribute__((unused)) GhostType ghost_type) {
AKANTU_DEBUG_IN();
if(this->plane_stress){
PlaneStressToolbox<2>::computeStress(el_type, ghost_type);
Array<Real>::const_scalar_iterator c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
computeTangentModuliOnQuad(tangent, grad_u, *c33_it);
++c33_it;
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
}
else{
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
computeTangentModuliOnQuad(tangent, grad_u);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialNeohookean<spatial_dimension>::getPushWaveSpeed(__attribute__((unused)) const Element & element) const {
return sqrt((this->lambda + 2 * this->mu) / this->rho);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialNeohookean<spatial_dimension>::getShearWaveSpeed(__attribute__((unused)) const Element & element) const {
return sqrt(this->mu / this->rho);
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialNeohookean);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
index 9e2fb8e42..a95a6998c 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
@@ -1,170 +1,171 @@
/**
* @file material_neohookean.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
- * @date creation: Mon Apr 08 2013
- * @date last modification: Tue Sep 16 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 08 2015
*
* @brief Material isotropic elastic
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material.hh"
#include "plane_stress_toolbox.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_NEOHOOKEAN_HH__
#define __AKANTU_MATERIAL_NEOHOOKEAN_HH__
__BEGIN_AKANTU__
/**
* Material elastic isotropic
*
* parameters in the material files :
* - rho : density (default: 0)
* - E : Young's modulus (default: 0)
* - nu : Poisson's ratio (default: 1/2)
* - Plane_Stress : if 0: plane strain, else: plane stress (default: 0)
*/
template<UInt spatial_dimension>
class MaterialNeohookean : public virtual PlaneStressToolbox<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialNeohookean(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialNeohookean() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material computed parameter
virtual void initMaterial();
/// constitutive law for all element of a type
virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// Computation of the cauchy stress for plane strain materials
virtual void computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// Non linear computation of the third direction strain in 2D plane stress case
virtual void computeThirdAxisDeformation(ElementType el_type, GhostType ghost_type = _not_ghost);
/// compute the elastic potential energy
virtual void computePotentialEnergy(ElementType el_type,
GhostType ghost_type = _not_ghost);
/// compute the tangent stiffness matrix for an element type
void computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost);
/// compute the p-wave speed in the material
virtual Real getPushWaveSpeed(const Element & element) const;
/// compute the s-wave speed in the material
virtual Real getShearWaveSpeed(const Element & element) const;
protected:
/// constitutive law for a given quadrature point
inline void computePiolaKirchhoffOnQuad(const Matrix<Real> &E,
Matrix<Real> &S);
/// constitutive law for a given quadrature point (first piola)
inline void computeFirstPiolaKirchhoffOnQuad(const Matrix<Real> &grad_u,
const Matrix<Real> &S,
Matrix<Real> &P);
/// constitutive law for a given quadrature point
inline void computeDeltaStressOnQuad(const Matrix<Real> & grad_u, const Matrix<Real> & grad_delta_u,
Matrix<Real> & delta_S);
/// constitutive law for a given quadrature point
inline void computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & S,
const Real & C33 = 1.0 );
/// constitutive law for a given quadrature point
inline void computeThirdAxisDeformationOnQuad(Matrix<Real> & grad_u, Real & c33_value);
/// constitutive law for a given quadrature point
//inline void updateStressOnQuad(const Matrix<Real> & sigma,
// Matrix<Real> & cauchy_sigma);
/// compute the potential energy for a quadrature point
inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
Real & epot);
/// compute the tangent stiffness matrix for an element
void computeTangentModuliOnQuad(Matrix<Real> & tangent,
Matrix<Real> & grad_u,
const Real & C33 = 1.0 );
/// recompute the lame coefficient if E or nu changes
virtual void updateInternalParameters();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the young modulus
Real E;
/// Poisson coefficient
Real nu;
/// First Lamé coefficient
Real lambda;
/// Second Lamé coefficient (shear modulus)
Real mu;
/// Bulk modulus
Real kpa;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_neohookean_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_NEOHOOKEAN_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
index 48fad2c3a..d088e3dfc 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
@@ -1,193 +1,193 @@
/**
* @file material_neohookean_inline_impl.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Mon Apr 08 2013
- * @date last modification: Tue Sep 16 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the inline functions of the material elastic
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <iostream>
#include <cmath>
#include "material_neohookean.hh"
using std::cout;
using std::endl;
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialNeohookean<dim>::computeDeltaStressOnQuad(const Matrix<Real> & grad_u, const Matrix<Real> & grad_delta_u,
Matrix<Real> & delta_S){
}
//! computes the second piola kirchhoff stress, called S
template<UInt dim>
inline void MaterialNeohookean<dim>::computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & S,
const Real & C33) {
//Neo hookean book
Matrix<Real> F(dim, dim);
Matrix<Real> C(dim, dim);//Right green
Matrix<Real> Cminus(dim, dim);//Right green
this->template gradUToF<dim > (grad_u, F);
this->rightCauchy(F, C);
Real J = F.det() * sqrt(C33); //the term sqrt(C33) corresponds to the off plane strain (2D plane stress)
// std::cout<<"det(F) -> "<<J<<std::endl;
Cminus.inverse(C);
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
S(i, j) = (i == j) * mu + (lambda * log(J) - mu) * Cminus(i, j);
}
/* -------------------------------------------------------------------------- */
class C33_NR : public Math::NewtonRaphsonFunctor {
public:
C33_NR(std::string name,
const Real & lambda,
const Real & mu,
const Matrix<Real> & C) :
NewtonRaphsonFunctor(name),
lambda(lambda), mu(mu), C(C) {}
inline Real f(Real x) const {
return (this->lambda/2. * (std::log(x) +
std::log(this->C(0,0)*this->C(1,1) -
Math::pow<2>(this->C(0,1)))) +
this->mu * (x - 1.));
}
inline Real f_prime(Real x) const {
AKANTU_DEBUG_ASSERT(std::abs(x) > Math::getTolerance(),
"x is zero (x should be the off plane right Cauchy" <<
" measure in this function so you made a mistake" <<
" somewhere else that lead to a zero here!!!");
return (this->lambda / (2. * x) + this->mu);
}
private:
const Real &lambda;
const Real & mu;
const Matrix<Real> & C;
};
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialNeohookean<dim>::computeThirdAxisDeformationOnQuad(Matrix<Real> & grad_u,
Real & c33_value) {
//Neo hookean book
Matrix<Real> F(dim, dim);
Matrix<Real> C(dim, dim);//Right green
this->template gradUToF<dim > (grad_u, F);
this->rightCauchy(F, C);
Math::NewtonRaphson nr(1e-5, 100);
c33_value = nr.solve(C33_NR("Neohookean_plan_stress", this->lambda, this->mu, C), c33_value);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialNeohookean<dim>::computePiolaKirchhoffOnQuad(const Matrix<Real> & E,
Matrix<Real> & S) {
Real trace = E.trace(); /// trace = (\nabla u)_{kk}
/// \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla u_{ij} + \nabla u_{ji})
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
S(i, j) = (i == j) * lambda * trace + 2.0 * mu * E(i, j);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void MaterialNeohookean<dim>::computeFirstPiolaKirchhoffOnQuad(
const Matrix<Real> & grad_u, const Matrix<Real> &S, Matrix<Real> &P) {
Matrix<Real> F(dim, dim);
Matrix<Real> C(dim, dim);//Right green
this->template gradUToF<dim > (grad_u, F);
// first Piola-Kirchhoff is computed as the product of the deformation gracient
// tensor and the second Piola-Kirchhoff stress tensor
P = F*S;
}
/**************************************************************************************/
/* Computation of the potential energy for a this neo hookean material */
template<UInt dim>
inline void MaterialNeohookean<dim>::computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
Real & epot){
Matrix<Real> F(dim, dim);
Matrix<Real> C(dim, dim);//Right green
this->template gradUToF<dim > (grad_u, F);
this->rightCauchy(F, C);
Real J = F.det();
// std::cout<<"det(F) -> "<<J<<std::endl;
epot=0.5*lambda*pow(log(J),2.)+ mu * (-log(J)+0.5*(C.trace()-dim));
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialNeohookean<dim>::computeTangentModuliOnQuad(Matrix<Real> & tangent,
Matrix<Real> & grad_u,
const Real & C33) {
//Neo hookean book
UInt cols = tangent.cols();
UInt rows = tangent.rows();
Matrix<Real> F(dim, dim);
Matrix<Real> C(dim, dim);
Matrix<Real> Cminus(dim, dim);
this->template gradUToF<dim > (grad_u, F);
this->rightCauchy(F, C);
Real J = F.det() * sqrt(C33);
// std::cout<<"det(F) -> "<<J<<std::endl;
Cminus.inverse(C);
for (UInt m = 0; m < rows; m++) {
UInt i = VoigtHelper<dim>::vec[m][0];
UInt j = VoigtHelper<dim>::vec[m][1];
for (UInt n = 0; n < cols; n++) {
UInt k = VoigtHelper<dim>::vec[n][0];
UInt l = VoigtHelper<dim>::vec[n][1];
//book belytchko
tangent(m, n) = lambda * Cminus(i, j) * Cminus(k, l) +
(mu - lambda * log(J)) * (Cminus(i, k) * Cminus(j, l) + Cminus(i, l) * Cminus(k, j));
}
}
}
/* -------------------------------------------------------------------------- */
diff --git a/src/model/solid_mechanics/materials/material_non_local.cc b/src/model/solid_mechanics/materials/material_non_local.cc
index 85bae8601..3a3e9dc6d 100644
--- a/src/model/solid_mechanics/materials/material_non_local.cc
+++ b/src/model/solid_mechanics/materials/material_non_local.cc
@@ -1,152 +1,156 @@
/**
* @file material_non_local.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Thu Oct 8 15:12:27 2015
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Tue Dec 08 2015
*
* @brief Implementation of material non-local
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_non_local.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt DIM>
MaterialNonLocal<DIM>::MaterialNonLocal(SolidMechanicsModel & model,
const ID & id) :
Material(model, id) {
AKANTU_DEBUG_IN();
NonLocalManager & manager = this->model->getNonLocalManager();
manager.registerNonLocalMaterial(*this);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialNonLocal<spatial_dimension>::~MaterialNonLocal() {
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNonLocal<spatial_dimension>::initMaterial() {
this->registerNeighborhood();
this->insertQuadsInNeighborhoods(_not_ghost);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNonLocal<spatial_dimension>::insertQuadsInNeighborhoods(GhostType ghost_type) {
NonLocalManager & manager = this->model->getNonLocalManager();
UInt _spatial_dimension = this->model->getSpatialDimension();
AKANTU_DEBUG_ASSERT(_spatial_dimension == spatial_dimension, "This assert was inserted because the current variable shadows a template parameter: cannot know which to use");
InternalField<Real> quadrature_points_coordinates("quadrature_points_coordinates_tmp_nl", *this);
quadrature_points_coordinates.initialize(spatial_dimension);
/// intialize quadrature point object
IntegrationPoint q;
q.ghost_type = ghost_type;
q.kind = _ek_regular;
Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_regular);
Mesh::type_iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_regular);
for(; it != last_type; ++it) {
q.type = *it;
const Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if(nb_element) {
UInt nb_quad = this->fem->getNbIntegrationPoints(*it, ghost_type);
UInt nb_tot_quad = nb_quad * nb_element;
Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
quads.resize(nb_tot_quad);
this->model->getFEEngine().computeIntegrationPointsCoordinates(quads, *it, ghost_type, elem_filter);
Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
UInt * elem = elem_filter.storage();
for (UInt e = 0; e < nb_element; ++e) {
q.element = *elem;
for (UInt nq = 0; nq < nb_quad; ++nq) {
q.num_point = nq;
q.global_num = q.element * nb_quad + nq;
manager.insertQuad(q, *quad, this->name);
++quad;
}
++elem;
}
}
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNonLocal<spatial_dimension>::updateNonLocalInternals(ElementTypeMapReal & non_local_flattened, const ID & field_id, const UInt nb_component) {
for (ghost_type_t::iterator g = ghost_type_t::begin(); g != ghost_type_t::end(); ++g) {
GhostType ghost_type = *g;
/// loop over all types in the material
typedef ElementTypeMapArray<UInt>:: type_iterator iterator;
iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_regular);
iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_regular);
for(; it != last_type; ++it) {
ElementType el_type = *it;
Array<Real> & internal = this->getInternal<Real>(field_id)(el_type, ghost_type);
Array<Real>::vector_iterator internal_it = internal.begin(nb_component);
Array<Real> & internal_flat = non_local_flattened(el_type, ghost_type);
Array<Real>::const_vector_iterator internal_flat_it = internal_flat.begin(nb_component);
/// loop all elements for the given type
const Array<UInt> & filter = this->element_filter(el_type,ghost_type);
UInt nb_elements = filter.getSize();
UInt nb_quads = this->getFEEngine().getNbIntegrationPoints(el_type, ghost_type);
for (UInt e = 0; e < nb_elements; ++e) {
UInt global_el = filter(e);
for (UInt q = 0; q < nb_quads; ++q, ++internal_it) {
UInt global_quad = global_el * nb_quads + q;
*internal_it = internal_flat_it[global_quad];
}
}
}
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNonLocal<spatial_dimension>::updateResidual(GhostType ghost_type) {
AKANTU_EXCEPTION("this method has not been implemented");
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNonLocal<spatial_dimension>::registerNeighborhood() {
this->model->getNonLocalManager().registerNeighborhood(this->name, this->name);
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialNonLocal);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_non_local.hh b/src/model/solid_mechanics/materials/material_non_local.hh
index 61f8d4515..b07deb02e 100644
--- a/src/model/solid_mechanics/materials/material_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_non_local.hh
@@ -1,100 +1,102 @@
/**
* @file material_non_local.hh
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Aug 31 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Material class that handle the non locality of a law for example damage.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material.hh"
#include "fe_engine.hh"
#include "non_local_manager.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_NON_LOCAL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt dim>
class MaterialNonLocal : public virtual Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialNonLocal(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialNonLocal();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material computed parameter
virtual void initMaterial();
virtual void updateResidual(GhostType ghost_type);
/// insert the quadrature points in the neighborhoods of the non-local manager
virtual void insertQuadsInNeighborhoods(GhostType ghost_type = _not_ghost);
/// update the values in the non-local internal fields
void updateNonLocalInternals(ElementTypeMapReal & non_local_flattened, const ID & field_id,
const UInt nb_component);
/// constitutive law
virtual void computeNonLocalStresses(GhostType ghost_type = _not_ghost) = 0;
/// register the neighborhoods for the material
virtual void registerNeighborhood();
protected:
virtual inline void onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event) {
AKANTU_DEBUG_ERROR("This is a case not taken into account!!!");
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_non_local_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_non_local_includes.hh b/src/model/solid_mechanics/materials/material_non_local_includes.hh
index 7280d38e5..203421601 100644
--- a/src/model/solid_mechanics/materials/material_non_local_includes.hh
+++ b/src/model/solid_mechanics/materials/material_non_local_includes.hh
@@ -1,39 +1,40 @@
/**
* @file material_non_local_includes.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Oct 31 2012
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Wed Nov 18 2015
*
* @brief Non local materials includes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_CMAKE_LIST_MATERIALS
# include "material_marigo_non_local.hh"
# include "material_mazars_non_local.hh"
#endif
#define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST \
((2, (marigo_non_local , MaterialMarigoNonLocal))) \
((2, (mazars_non_local , MaterialMazarsNonLocal)))
diff --git a/src/model/solid_mechanics/materials/material_non_local_inline_impl.cc b/src/model/solid_mechanics/materials/material_non_local_inline_impl.cc
index 717767067..893ff9745 100644
--- a/src/model/solid_mechanics/materials/material_non_local_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_non_local_inline_impl.cc
@@ -1,34 +1,36 @@
/**
* @file material_non_local_inline_impl.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 31 2011
- * @date last modification: Mon Jun 23 2014
+ * @date last modification: Thu Oct 08 2015
*
* @brief Non-local inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
__END_AKANTU__
__BEGIN_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
index 0d46f95f9..2dd8d27e5 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
@@ -1,215 +1,216 @@
/**
* @file material_linear_isotropic_hardening.cc
*
- * @author Lucas Frerot <lucas.frerot@epfl.ch>
- * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
+ * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Oct 03 2013
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Mon Apr 07 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief Specialization of the material class for isotropic finite deformation linear hardening plasticity
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_linear_isotropic_hardening.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt dim>
MaterialLinearIsotropicHardening<dim>::MaterialLinearIsotropicHardening(SolidMechanicsModel & model,
const ID & id) :
Material(model, id), MaterialPlastic<dim>(model, id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialLinearIsotropicHardening<spatial_dimension>::MaterialLinearIsotropicHardening(
SolidMechanicsModel & model,
UInt dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id) :
Material(model, dim, mesh, fe_engine, id),
MaterialPlastic<spatial_dimension>(model, dim, mesh, fe_engine, id)
{}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialLinearIsotropicHardening<spatial_dimension>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialThermal<spatial_dimension>::computeStress(el_type, ghost_type);
// infinitesimal and finite deformation
Array<Real>::iterator<> sigma_th_it =
this->sigma_th(el_type, ghost_type).begin();
Array<Real>::iterator<> previous_sigma_th_it =
this->sigma_th.previous(el_type, ghost_type).begin();
Array<Real>::matrix_iterator previous_gradu_it =
this->gradu.previous(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator previous_stress_it =
this->stress.previous(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator inelastic_strain_it =
this->inelastic_strain(el_type, ghost_type).begin(spatial_dimension,spatial_dimension);
Array<Real>::matrix_iterator previous_inelastic_strain_it =
this->inelastic_strain.previous(el_type, ghost_type).begin(spatial_dimension,spatial_dimension);
Array<Real>::iterator<> iso_hardening_it =
this->iso_hardening(el_type, ghost_type).begin();
Array<Real>::iterator<> previous_iso_hardening_it =
this->iso_hardening.previous(el_type, ghost_type).begin();
//
// Finite Deformations
//
if (this->finite_deformation) {
Array<Real>::matrix_iterator previous_piola_kirchhoff_2_it =
this->piola_kirchhoff_2.previous(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator green_strain_it =
this->green_strain(el_type, ghost_type).begin(spatial_dimension,spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & inelastic_strain_tensor = *inelastic_strain_it;
Matrix<Real> & previous_inelastic_strain_tensor = *previous_inelastic_strain_it;
Matrix<Real> & previous_grad_u = *previous_gradu_it;
Matrix<Real> & previous_sigma = *previous_piola_kirchhoff_2_it;
Matrix<Real> & green_strain = *green_strain_it;
this->template gradUToGreenStrain<spatial_dimension>(grad_u, green_strain);
Matrix<Real> previous_green_strain(spatial_dimension,spatial_dimension);
this->template gradUToGreenStrain<spatial_dimension>(previous_grad_u, previous_green_strain);
Matrix<Real> F_tensor(spatial_dimension,spatial_dimension);
this->template gradUToF<spatial_dimension>(grad_u,F_tensor);
computeStressOnQuad(green_strain,
previous_green_strain,
sigma,
previous_sigma,
inelastic_strain_tensor,
previous_inelastic_strain_tensor,
*iso_hardening_it,
*previous_iso_hardening_it,
*sigma_th_it,
*previous_sigma_th_it,
F_tensor);
++sigma_th_it;
++inelastic_strain_it;
++iso_hardening_it;
++previous_sigma_th_it;
//++previous_stress_it;
++previous_gradu_it;
++green_strain_it;
++previous_inelastic_strain_it;
++previous_iso_hardening_it;
++previous_piola_kirchhoff_2_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
// Infinitesimal deformations
else {
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & inelastic_strain_tensor = *inelastic_strain_it;
Matrix<Real> & previous_inelastic_strain_tensor = *previous_inelastic_strain_it;
Matrix<Real> & previous_grad_u = *previous_gradu_it;
Matrix<Real> & previous_sigma = *previous_stress_it;
computeStressOnQuad(grad_u,
previous_grad_u,
sigma,
previous_sigma,
inelastic_strain_tensor,
previous_inelastic_strain_tensor,
*iso_hardening_it,
*previous_iso_hardening_it,
*sigma_th_it,
*previous_sigma_th_it);
++sigma_th_it;
++inelastic_strain_it;
++iso_hardening_it;
++previous_sigma_th_it;
++previous_stress_it;
++previous_gradu_it;
++previous_inelastic_strain_it;
++previous_iso_hardening_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialLinearIsotropicHardening<spatial_dimension>::computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
Array<Real> & tangent_matrix,
__attribute__((unused)) GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::const_matrix_iterator previous_gradu_it =
this->gradu.previous(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::const_matrix_iterator previous_stress_it =
this->stress.previous(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::const_scalar_iterator iso_hardening= this->iso_hardening(el_type, ghost_type).begin();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
computeTangentModuliOnQuad(tangent, grad_u, *previous_gradu_it, sigma_tensor, *previous_stress_it, *iso_hardening);
++previous_gradu_it;
++previous_stress_it;
++iso_hardening;
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialLinearIsotropicHardening);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
index 933bd414a..c148bea69 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
@@ -1,118 +1,121 @@
/**
* @file material_linear_isotropic_hardening.hh
*
- * @author Lucas Frerot <lucas.frerot@epfl.ch>
- * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@eplf.ch>
+ * @author Benjamin Paccaud <bpaccaud@epfl.ch>
+ * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Oct 03 2013
- * @date last modification: Mon Apr 07 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Mon Jun 01 2015
*
* @brief Specialization of the material class for isotropic finite deformation linear hardening plasticity
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_voigthelper.hh"
#include "material_plastic.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_LINEAR_ISOTROPIC_HARDENING_HH__
#define __AKANTU_MATERIAL_LINEAR_ISOTROPIC_HARDENING_HH__
__BEGIN_AKANTU__
/**
* Material plastic with a linear evolution of the yielding stress
*/
template <UInt spatial_dimension>
class MaterialLinearIsotropicHardening : public MaterialPlastic<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialLinearIsotropicHardening(SolidMechanicsModel & model, const ID & id = "");
MaterialLinearIsotropicHardening(SolidMechanicsModel & model,
UInt dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// constitutive law for all element of a type
virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// compute the tangent stiffness matrix for an element type
void computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost);
protected:
/// Infinitesimal deformations
inline void computeStressOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & previous_grad_u,
Matrix<Real> & sigma,
const Matrix<Real> & previous_sigma,
Matrix<Real> & inelas_strain,
const Matrix<Real> & previous_inelas_strain,
Real & iso_hardening,
const Real & previous_iso_hardening,
const Real & sigma_th,
const Real & previous_sigma_th);
/// Finite deformations
inline void computeStressOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & previous_grad_u,
Matrix<Real> & sigma,
const Matrix<Real> & previous_sigma,
Matrix<Real> & inelas_strain,
const Matrix<Real> & previous_inelas_strain,
Real & iso_hardening,
const Real & previous_iso_hardening,
const Real & sigma_th,
const Real & previous_sigma_th,
const Matrix<Real> & F_tensor);
inline void computeTangentModuliOnQuad(Matrix<Real> & tangent,
const Matrix<Real> & grad_u,
const Matrix<Real> & previous_grad_u,
const Matrix<Real> & sigma_tensor,
const Matrix<Real> & previous_sigma_tensor,
const Real & iso_hardening) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_linear_isotropic_hardening_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_LINEAR_ISOTROPIC_HARDENING_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
index 609e3b199..43cef18de 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
@@ -1,307 +1,307 @@
/**
* @file material_linear_isotropic_hardening_inline_impl.cc
*
+ * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
* @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
- * @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
*
- * @date creation: Thu Oct 03 2013
- * @date last modification: Mon Jun 09 2014
+ * @date creation: Mon Apr 07 2014
+ * @date last modification: Fri May 29 2015
*
* @brief Implementation of the inline functions of the material plasticity
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "material_linear_isotropic_hardening.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
///Infinitesimal deformations
template<UInt dim>
inline void
MaterialLinearIsotropicHardening<dim>::computeStressOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & previous_grad_u,
Matrix<Real> & sigma,
const Matrix<Real> & previous_sigma,
Matrix<Real> & inelastic_strain,
const Matrix<Real> & previous_inelastic_strain,
Real & iso_hardening,
const Real & previous_iso_hardening,
const Real & sigma_th,
const Real & previous_sigma_th) {
//Infinitesimal plasticity
Real dp = 0.0;
Real d_dp = 0.0;
UInt n = 0;
Real delta_sigma_th = sigma_th - previous_sigma_th;
Matrix<Real> grad_delta_u(grad_u);
grad_delta_u -= previous_grad_u;
//Compute trial stress, sigma_tr
Matrix<Real> sigma_tr(dim, dim);
MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr, delta_sigma_th);
sigma_tr += previous_sigma;
// Compute deviatoric trial stress, sigma_tr_dev
Matrix<Real> sigma_tr_dev(sigma_tr);
sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
// Compute effective deviatoric trial stress
Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
Real sigma_tr_dev_eff = std::sqrt(3./2. * s);
// In 1D Von-Mises stress is the stress
if (dim == 1) sigma_tr_dev_eff = sigma_tr(0, 0);
const Real iso_hardening_t = previous_iso_hardening;
iso_hardening = iso_hardening_t;
//Loop for correcting stress based on yield function
bool initial_yielding = ( (sigma_tr_dev_eff - iso_hardening - this->sigma_y) > 0) ;
while (initial_yielding && std::abs(sigma_tr_dev_eff - iso_hardening - this->sigma_y) > Math::getTolerance()) {
d_dp = (sigma_tr_dev_eff - 3. * this->mu *dp - iso_hardening - this->sigma_y)
/ (3. * this->mu + this->h);
dp = dp + d_dp;
iso_hardening = iso_hardening_t + this->h * dp;
++n;
if (d_dp < 1e-5) {
break;
} else if (n > 50) {
AKANTU_DEBUG_WARNING("Isotropic hardening convergence failed");
break;
}
}
//Update internal variable
Matrix<Real> delta_inelastic_strain(dim, dim, 0.);
if (std::abs(sigma_tr_dev_eff) >
sigma_tr_dev.norm<L_inf>() * Math::getTolerance()) {
delta_inelastic_strain.copy(sigma_tr_dev);
delta_inelastic_strain *= 3./2. * dp / sigma_tr_dev_eff;
}
MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(grad_delta_u, sigma, previous_sigma,
inelastic_strain, previous_inelastic_strain,
delta_inelastic_strain);
}
/* -------------------------------------------------------------------------- */
///Finite deformations
template<UInt dim>
inline void
MaterialLinearIsotropicHardening<dim>::computeStressOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & previous_grad_u,
Matrix<Real> & sigma,
const Matrix<Real> & previous_sigma,
Matrix<Real> & inelastic_strain,
const Matrix<Real> & previous_inelastic_strain,
Real & iso_hardening,
const Real & previous_iso_hardening,
const Real & sigma_th,
const Real & previous_sigma_th,
const Matrix<Real> & F_tensor) {
//Finite plasticity
Real dp=0.0;
Real d_dp=0.0;
UInt n=0;
Real delta_sigma_th = sigma_th - previous_sigma_th;
Matrix<Real> grad_delta_u(grad_u);
grad_delta_u -= previous_grad_u;
//Compute trial stress, sigma_tr
Matrix<Real> sigma_tr(dim, dim);
MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr, delta_sigma_th);
sigma_tr += previous_sigma;
// Compute deviatoric trial stress, sigma_tr_dev
Matrix<Real> sigma_tr_dev(sigma_tr);
sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
// Compute effective deviatoric trial stress
Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
Real sigma_tr_dev_eff = std::sqrt(3./2. * s);
// compute the cauchy stress to apply the Von-Mises criterion
Matrix<Real> cauchy_stress(dim,dim);
Material::computeCauchyStressOnQuad<dim>(F_tensor,sigma_tr,cauchy_stress);
Matrix<Real> cauchy_stress_dev(cauchy_stress);
cauchy_stress_dev -= Matrix<Real>::eye(dim, cauchy_stress.trace() / 3.0);
Real c = cauchy_stress_dev.doubleDot(cauchy_stress_dev);
Real cauchy_stress_dev_eff = std::sqrt(3./2. * c);
const Real iso_hardening_t = previous_iso_hardening;
iso_hardening = iso_hardening_t;
//Loop for correcting stress based on yield function
// F is written in terms of S
// bool initial_yielding = ( (sigma_tr_dev_eff - iso_hardening - this->sigma_y) > 0) ;
// while ( initial_yielding && std::abs(sigma_tr_dev_eff - iso_hardening - this->sigma_y) > Math::getTolerance() ) {
// d_dp = (sigma_tr_dev_eff - 3. * this->mu *dp - iso_hardening - this->sigma_y)
// / (3. * this->mu + this->h);
// //r = r + h * dp;
// dp = dp + d_dp;
// iso_hardening = iso_hardening_t + this->h * dp;
// ++n;
// /// TODO : explicit this criterion with an error message
// if ((std::abs(d_dp) < 1e-9) || (n>50)){
// AKANTU_DEBUG_INFO("convergence of increment of plastic strain. d_dp:" << d_dp << "\tNumber of iteration:"<<n);
// break;
// }
// }
// F is written in terms of cauchy stress
bool initial_yielding = ( (cauchy_stress_dev_eff - iso_hardening - this->sigma_y) > 0) ;
while ( initial_yielding && std::abs(cauchy_stress_dev_eff - iso_hardening - this->sigma_y) > Math::getTolerance() ) {
d_dp = ( cauchy_stress_dev_eff - 3. * this->mu *dp - iso_hardening - this->sigma_y)
/ (3. * this->mu + this->h);
//r = r + h * dp;
dp = dp + d_dp;
iso_hardening = iso_hardening_t + this->h * dp;
++n;
/// TODO : explicit this criterion with an error message
if ((d_dp < 1e-5) || (n>50)){
AKANTU_DEBUG_INFO("convergence of increment of plastic strain. d_dp:" << d_dp << "\tNumber of iteration:"<<n);
break;
}
}
//Update internal variable
Matrix<Real> delta_inelastic_strain(dim, dim, 0.);
if (std::abs(sigma_tr_dev_eff) >
sigma_tr_dev.norm<L_inf>() * Math::getTolerance()) {
// /// compute the direction of the plastic strain as \frac{\partial F}{\partial S} = \frac{3}{2J\sigma_{effective}}} Ft \sigma_{dev} F
Matrix<Real> cauchy_dev_F(dim,dim);
cauchy_dev_F.mul<false,false>(F_tensor,cauchy_stress_dev);
Real J = F_tensor.det();
Real constant = J ? 1./J : 0;
constant *= 3. * dp / (2. * cauchy_stress_dev_eff);
delta_inelastic_strain.mul<true,false>(F_tensor,cauchy_dev_F,constant);
//Direction given by the piola kirchhoff deviatoric tensor \frac{\partial F}{\partial S} = \frac{3}{2\sigma_{effective}}}S_{dev}
// delta_inelastic_strain.copy(sigma_tr_dev);
// delta_inelastic_strain *= 3./2. * dp / sigma_tr_dev_eff;
}
MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(grad_delta_u, sigma, previous_sigma,
inelastic_strain, previous_inelastic_strain,
delta_inelastic_strain);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void
MaterialLinearIsotropicHardening<dim>::computeTangentModuliOnQuad(Matrix<Real> & tangent,
const Matrix<Real> & grad_u,
const Matrix<Real> & previous_grad_u,
const Matrix<Real> & sigma_tensor,
const Matrix<Real> & previous_sigma_tensor,
const Real & iso_hardening) const {
// Real r=iso_hardening;
// Matrix<Real> grad_delta_u(grad_u);
// grad_delta_u -= previous_grad_u;
// //Compute trial stress, sigma_tr
// Matrix<Real> sigma_tr(dim, dim);
// MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr);
// sigma_tr += previous_sigma_tensor;
// // Compute deviatoric trial stress, sigma_tr_dev
// Matrix<Real> sigma_tr_dev(sigma_tr);
// sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
// // Compute effective deviatoric trial stress
// Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
// Real sigma_tr_dev_eff=std::sqrt(3./2. * s);
// // Compute deviatoric stress, sigma_dev
// Matrix<Real> sigma_dev(sigma_tensor);
// sigma_dev -= Matrix<Real>::eye(dim, sigma_tensor.trace() / 3.0);
// // Compute effective deviatoric stress
// s = sigma_dev.doubleDot(sigma_dev);
// Real sigma_dev_eff = std::sqrt(3./2. * s);
// Real xr = 0.0;
// if(sigma_tr_dev_eff > sigma_dev_eff * Math::getTolerance())
// xr = sigma_dev_eff / sigma_tr_dev_eff;
// Real __attribute__((unused)) q = 1.5 * (1. / (1. + 3. * this->mu / this->h) - xr);
/*
UInt cols = tangent.cols();
UInt rows = tangent.rows();
for (UInt m = 0; m < rows; ++m) {
UInt i = VoigtHelper<dim>::vec[m][0];
UInt j = VoigtHelper<dim>::vec[m][1];
for (UInt n = 0; n < cols; ++n) {
UInt k = VoigtHelper<dim>::vec[n][0];
UInt l = VoigtHelper<dim>::vec[n][1];
*/
// This section of the code is commented
// There were some problems with the convergence of plastic-coupled simulations with thermal expansion
// XXX: DO NOT REMOVE
/*if (((sigma_tr_dev_eff-iso_hardening-sigmay) > 0) && (xr > 0)) {
tangent(m,n) =
2. * this->mu * q * (sigma_tr_dev (i,j) / sigma_tr_dev_eff) * (sigma_tr_dev (k,l) / sigma_tr_dev_eff) +
(i==k) * (j==l) * 2. * this->mu * xr +
(i==j) * (k==l) * (this->kpa - 2./3. * this->mu * xr);
if ((m == n) && (m>=dim))
tangent(m, n) = tangent(m, n) - this->mu * xr;
} else {*/
/*
tangent(m,n) = (i==k) * (j==l) * 2. * this->mu +
(i==j) * (k==l) * this->lambda;
tangent(m,n) -= (m==n) * (m>=dim) * this->mu;
*/
//}
//correct tangent stiffness for shear component
//}
//}
MaterialElastic<dim>::computeTangentModuliOnQuad(tangent);
}
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc b/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
index 5f224990f..bdcb5c66d 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
@@ -1,202 +1,203 @@
/**
* @file material_plastic.cc
*
- * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Apr 07 2014
- * @date last modification: Fri Jun 13 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief Implemantation of the akantu::MaterialPlastic class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_plastic.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialPlastic<spatial_dimension>::MaterialPlastic(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
MaterialElastic<spatial_dimension>(model, id),
iso_hardening("iso_hardening", *this),
inelastic_strain("inelastic_strain", *this),
plastic_energy("plastic_energy", *this),
d_plastic_energy("d_plastic_energy", *this) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
template<UInt spatial_dimension>
MaterialPlastic<spatial_dimension>::MaterialPlastic(SolidMechanicsModel & model,
UInt dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id) :
Material(model, dim, mesh, fe_engine, id),
MaterialElastic<spatial_dimension>(model, dim, mesh, fe_engine, id),
iso_hardening ("iso_hardening" , *this, dim, fe_engine, this->element_filter),
inelastic_strain("inelastic_strain", *this, dim, fe_engine, this->element_filter),
plastic_energy ("plastic_energy" , *this, dim, fe_engine, this->element_filter),
d_plastic_energy("d_plastic_energy", *this, dim, fe_engine, this->element_filter) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialPlastic<spatial_dimension>::initialize() {
this->registerParam( "h", h, Real(0.), _pat_parsable | _pat_modifiable, "Hardening modulus");
this->registerParam("sigma_y", sigma_y, Real(0.), _pat_parsable | _pat_modifiable, "Yield stress");
this->iso_hardening.initialize(1);
this->iso_hardening.initializeHistory();
this->plastic_energy.initialize(1);
this->d_plastic_energy.initialize(1);
this->use_previous_stress = true;
this->use_previous_gradu = true;
this->use_previous_stress_thermal = true;
this->inelastic_strain.initialize(spatial_dimension * spatial_dimension);
this->inelastic_strain.initializeHistory();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialPlastic<spatial_dimension>::getEnergy(std::string type) {
if (type == "plastic") return getPlasticEnergy();
else return MaterialElastic<spatial_dimension>::getEnergy(type);
return 0.;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialPlastic<spatial_dimension>::getPlasticEnergy() {
AKANTU_DEBUG_IN();
Real penergy = 0.;
const Mesh & mesh = this->model->getFEEngine().getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, _not_ghost);
for(; it != end; ++it) {
penergy += this->model->getFEEngine().integrate(plastic_energy(*it, _not_ghost),
*it, _not_ghost,
this->element_filter(*it, _not_ghost));
}
AKANTU_DEBUG_OUT();
return penergy;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialPlastic<spatial_dimension>::computePotentialEnergy(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
if(ghost_type != _not_ghost) return;
Array<Real>::scalar_iterator epot = this->potential_energy(el_type, ghost_type).begin();
Array<Real>::const_iterator< Matrix<Real> > inelastic_strain_it
= this->inelastic_strain(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> elastic_strain(spatial_dimension, spatial_dimension);
elastic_strain.copy(grad_u);
elastic_strain -= *inelastic_strain_it;
MaterialElastic<spatial_dimension>::computePotentialEnergyOnQuad(elastic_strain, sigma, *epot);
++epot;
++inelastic_strain_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialPlastic<spatial_dimension>::updateEnergies(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialElastic<spatial_dimension>::updateEnergies(el_type, ghost_type);
Array<Real>::iterator<> pe_it =
this->plastic_energy(el_type, ghost_type).begin();
Array<Real>::iterator<> wp_it =
this->d_plastic_energy(el_type, ghost_type).begin();
Array<Real>::iterator< Matrix<Real> > inelastic_strain_it =
this->inelastic_strain(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::iterator< Matrix<Real> > previous_inelastic_strain_it =
this->inelastic_strain.previous(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator previous_sigma =
this->stress.previous(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> delta_strain_it(*inelastic_strain_it);
delta_strain_it -= *previous_inelastic_strain_it;
Matrix<Real> sigma_h(sigma);
sigma_h += *previous_sigma;
*wp_it = .5 * sigma_h.doubleDot(delta_strain_it);
*pe_it += *wp_it;
++pe_it;
++wp_it;
++inelastic_strain_it;
++previous_inelastic_strain_it;
++previous_sigma;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialPlastic);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh b/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
index ec3ad3f78..d4072311e 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
@@ -1,140 +1,142 @@
/**
* @file material_plastic.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Apr 07 2014
- * @date last modification: Mon Apr 07 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 08 2015
*
* @brief Common interface for plastic materials
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_elastic.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_PLASTIC_HH__
#define __AKANTU_MATERIAL_PLASTIC_HH__
__BEGIN_AKANTU__
/**
* Parent class for the plastic constitutive laws
* parameters in the material files :
* - h : Hardening parameter (default: 0)
* - sigmay : Yield stress
*/
template<UInt dim>
class MaterialPlastic : public MaterialElastic<dim> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialPlastic(SolidMechanicsModel & model, const ID & id = "");
MaterialPlastic(SolidMechanicsModel & model,
UInt a_dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id = "");
protected:
void initialize();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get the energy specifying the type for the time step
virtual Real getEnergy(std::string type);
/// Compute the plastic energy
virtual void updateEnergies(ElementType el_type, GhostType ghost_type = _not_ghost);
/// Compute the true potential energy
virtual void computePotentialEnergy(ElementType el_type, GhostType ghost_type);
protected:
/// compute the stress and inelastic strain for the quadrature point
inline void computeStressAndInelasticStrainOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & previous_grad_u,
Matrix<Real> & sigma,
const Matrix<Real> & previous_sigma,
Matrix<Real> & inelas_strain,
const Matrix<Real> & previous_inelas_strain,
const Matrix<Real> & delta_inelastic_strain) const;
inline void computeStressAndInelasticStrainOnQuad(const Matrix<Real> & delta_grad_u,
Matrix<Real> & sigma,
const Matrix<Real> & previous_sigma,
Matrix<Real> & inelas_strain,
const Matrix<Real> & previous_inelas_strain,
const Matrix<Real> & delta_inelastic_strain) const;
/// get the plastic energy for the time step
Real getPlasticEnergy();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Yield stresss
Real sigma_y;
/// hardening modulus
Real h;
/// isotropic hardening, r
InternalField<Real> iso_hardening;
/// inelastic strain arrays ordered by element types (inelastic deformation)
InternalField<Real> inelastic_strain;
/// Plastic energy
InternalField<Real> plastic_energy;
/// @todo : add a coefficient beta that will multiply the plastic energy increment
/// to compute the energy converted to heat
/// Plastic energy increment
InternalField<Real> d_plastic_energy;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_plastic_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_PLASTIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc b/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
index 6359d381f..627f18cf9 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
@@ -1,68 +1,69 @@
/**
* @file material_plastic_inline_impl.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Apr 07 2014
- * @date last modification: Mon Apr 07 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief Implementation of the inline functions of akantu::MaterialPlastic
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void
MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(const Matrix<Real> & delta_grad_u,
Matrix<Real> & sigma,
const Matrix<Real> & previous_sigma,
Matrix<Real> & inelastic_strain,
const Matrix<Real> & previous_inelastic_strain,
const Matrix<Real> & delta_inelastic_strain) const {
Matrix<Real> grad_u_elastic(dim, dim);
grad_u_elastic.copy(delta_grad_u);
grad_u_elastic -= delta_inelastic_strain;
Matrix<Real> sigma_elastic(dim, dim);
MaterialElastic<dim>::computeStressOnQuad(grad_u_elastic, sigma_elastic);
sigma.copy(previous_sigma);
sigma += sigma_elastic;
inelastic_strain.copy(previous_inelastic_strain);
inelastic_strain += delta_inelastic_strain;
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void
MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & previous_grad_u,
Matrix<Real> & sigma,
const Matrix<Real> & previous_sigma,
Matrix<Real> & inelastic_strain,
const Matrix<Real> & previous_inelastic_strain,
const Matrix<Real> & delta_inelastic_strain) const {
Matrix<Real> delta_grad_u(grad_u);
delta_grad_u -= previous_grad_u;
computeStressAndInelasticStrainOnQuad(delta_grad_u, sigma, previous_sigma,
inelastic_strain, previous_inelastic_strain, delta_inelastic_strain);
}
diff --git a/src/model/solid_mechanics/materials/material_python/material_python.cc b/src/model/solid_mechanics/materials/material_python/material_python.cc
index 4722077fc..5d6125b88 100644
--- a/src/model/solid_mechanics/materials/material_python/material_python.cc
+++ b/src/model/solid_mechanics/materials/material_python/material_python.cc
@@ -1,125 +1,155 @@
+/**
+ * @file material_python.cc
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ *
+ * @date creation: Fri Nov 13 2015
+ * @date last modification: Fri Nov 13 2015
+ *
+ * @brief Material python implementation
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
/**
* @file material_python.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
*/
/* -------------------------------------------------------------------------- */
#include "material_python.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
MaterialPython::MaterialPython(SolidMechanicsModel & model,
PyObject * obj,
const ID & id) :
Material(model, id),
PythonFunctor(obj){
AKANTU_DEBUG_IN();
this->registerInternals();
std::vector<std::string> param_names = this->callFunctor<std::vector<std::string> >("registerParam");
this->local_params.resize(param_names.size());
for (UInt i = 0; i < param_names.size(); ++i) {
std::stringstream sstr;
sstr << "PythonParameter" << i;
this->registerParam(param_names[i],local_params[i],0., _pat_parsable,sstr.str() );
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialPython::registerInternals() {
std::vector<std::string> internal_names = this->callFunctor<std::vector<std::string> >("registerInternals");
this->internals.resize(internal_names.size());
for (UInt i = 0; i < internal_names.size(); ++i) {
std::stringstream sstr;
sstr << "PythonInternal" << i;
this->internals[i] = new InternalField<Real>(internal_names[i],*this);
this->internals[i]->initialize(1);
}
}
/* -------------------------------------------------------------------------- */
void MaterialPython::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
// initInternalArray(this->damage, 1);
// resizeInternalArray(this->damage);
// lambda = nu * E / ((1 + nu) * (1 - 2*nu));
// mu = E / (2 * (1 + nu));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialPython::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
typedef Array<Real>::iterator<Real> it_type;
std::vector<it_type> its;
for (auto i: this->internals) {
its.push_back((*i)(el_type,ghost_type).begin());
}
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeStress(grad_u, sigma, its);
for (auto b: its) ++(*b);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename it_type>
void MaterialPython::computeStress( Matrix<Real> & grad_u,
Matrix<Real> & sigma,
std::vector<it_type> & internal_iterators){
std::vector<Real> inputs;
for (auto i: internal_iterators){
inputs.push_back(*i);
}
this->callFunctor<void>("computeStress",grad_u,sigma,inputs);
for (UInt i = 0; i < inputs.size(); ++i) {
*internal_iterators[i] = inputs[i];
}
}
/* -------------------------------------------------------------------------- */
void MaterialPython::computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type){
this->callFunctor<void>("computeTangentModuli",el_type,tangent_matrix,ghost_type);
}
/* -------------------------------------------------------------------------- */
Real MaterialPython::getPushWaveSpeed(const Element & element) const{
return this->callFunctor<Real>("getPushWaveSpeed");
}
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_python/material_python.hh b/src/model/solid_mechanics/materials/material_python/material_python.hh
index 7abb45fe2..84b43872c 100644
--- a/src/model/solid_mechanics/materials/material_python/material_python.hh
+++ b/src/model/solid_mechanics/materials/material_python/material_python.hh
@@ -1,93 +1,123 @@
+/**
+ * @file material_python.hh
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ *
+ * @date creation: Fri Nov 13 2015
+ * @date last modification: Fri Nov 13 2015
+ *
+ * @brief Python material
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
/**
* @file material_python.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_PYTHON_HH__
#define __AKANTU_MATERIAL_PYTHON_HH__
/* -------------------------------------------------------------------------- */
#include "python_functor.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class MaterialPython : public Material, PythonFunctor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialPython(SolidMechanicsModel & model, PyObject * obj, const ID & id = "");
virtual ~MaterialPython() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void registerInternals();
virtual void initMaterial();
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// constitutive law for a given quad point
template <typename it_type>
void computeStress(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
std::vector<it_type> & internal_iterators);
/// compute the tangent stiffness matrix for an element type
virtual void computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost);
/// compute the push wave speed of the material
Real getPushWaveSpeed(const Element & element) const;
protected:
/// update the dissipated energy, must be called after the stress have been computed
//virtual void updateEnergies(ElementType el_type, GhostType ghost_type){};
/// compute the tangent stiffness matrix for a given quadrature point
//inline void computeTangentModuliOnQuad(Matrix<Real> & tangent, Real & dam){};
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
//virtual Real getEnergy(std::string type){};
//virtual Real getEnergy(std::string energy_id, ElementType type, UInt index){};
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
std::vector<Real> local_params;
std::vector<InternalField<Real> *> internals;
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_PYTHON_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_thermal.cc b/src/model/solid_mechanics/materials/material_thermal.cc
index c799bc65e..6c54c86c7 100644
--- a/src/model/solid_mechanics/materials/material_thermal.cc
+++ b/src/model/solid_mechanics/materials/material_thermal.cc
@@ -1,122 +1,123 @@
/**
* @file material_thermal.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Thu Oct 17 2013
- * @date last modification: Thu Apr 03 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Aug 04 2015
*
* @brief Specialization of the material class for the thermal material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_thermal.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialThermal<spatial_dimension>::MaterialThermal(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
delta_T("delta_T", *this),
sigma_th("sigma_th", *this),
use_previous_stress_thermal(false) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialThermal<spatial_dimension>::MaterialThermal(SolidMechanicsModel & model,
UInt dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id) :
Material(model, dim, mesh, fe_engine, id),
delta_T("delta_T", *this, dim, fe_engine, this->element_filter),
sigma_th("sigma_th", *this, dim, fe_engine, this->element_filter),
use_previous_stress_thermal(false) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
template<UInt spatial_dimension>
void MaterialThermal<spatial_dimension>::initialize() {
this->registerParam("E" , E , Real(0. ) , _pat_parsable | _pat_modifiable, "Young's modulus" );
this->registerParam("nu" , nu , Real(0.5) , _pat_parsable | _pat_modifiable, "Poisson's ratio" );
this->registerParam("alpha" , alpha , Real(0. ) , _pat_parsable | _pat_modifiable, "Thermal expansion coefficient");
this->registerParam("delta_T", delta_T, _pat_parsable | _pat_modifiable, "Uniform temperature field");
delta_T.initialize(1);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialThermal<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
sigma_th.initialize(1);
if(use_previous_stress_thermal) {
sigma_th.initializeHistory();
}
Material::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void MaterialThermal<dim>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::iterator<> delta_t_it = this->delta_T(el_type, ghost_type).begin();
Array<Real>::iterator<> sigma_th_it = this->sigma_th(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
/// TODO : implement with the matrix alpha
if (dim == 1) {
*sigma_th_it = - this->E * this->alpha * *delta_t_it;
}
else {
*sigma_th_it = - this->E/(1.-2.*this->nu) * this->alpha * *delta_t_it;
}
++delta_t_it;
++sigma_th_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialThermal);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_thermal.hh b/src/model/solid_mechanics/materials/material_thermal.hh
index 9e120c0d2..65aeda8be 100644
--- a/src/model/solid_mechanics/materials/material_thermal.hh
+++ b/src/model/solid_mechanics/materials/material_thermal.hh
@@ -1,104 +1,105 @@
/**
* @file material_thermal.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Thu Oct 17 2013
- * @date last modification: Thu Apr 03 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Aug 18 2015
*
* @brief Material isotropic thermo-elastic
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_THERMAL_HH__
#define __AKANTU_MATERIAL_THERMAL_HH__
__BEGIN_AKANTU__
template<UInt spatial_dimension>
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<Real> delta_T;
/// Current thermal stress
InternalField<Real> 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/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
index 564882e77..e013734bd 100644
--- a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
+++ b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
@@ -1,298 +1,299 @@
/**
* @file material_standard_linear_solid_deviatoric.cc
*
- * @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
*
- * @date creation: Wed Feb 08 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Wed May 04 2011
+ * @date last modification: Thu Oct 15 2015
*
* @brief Material Visco-elastic
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_standard_linear_solid_deviatoric.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialStandardLinearSolidDeviatoric<spatial_dimension>::MaterialStandardLinearSolidDeviatoric(SolidMechanicsModel & model, const ID & id) :
Material(model, id), MaterialElastic<spatial_dimension>(model, id),
stress_dev("stress_dev", *this),
history_integral("history_integral", *this),
dissipated_energy("dissipated_energy", *this) {
AKANTU_DEBUG_IN();
this->registerParam("Eta", eta, Real(1.), ParamAccessType(_pat_parsable | _pat_modifiable), "Viscosity");
this->registerParam("Ev", Ev, Real(1.), ParamAccessType(_pat_parsable | _pat_modifiable), "Stiffness of the viscous element");
this->registerParam("Einf", E_inf, Real(1.), ParamAccessType(_pat_readable), "Stiffness of the elastic element");
UInt stress_size = spatial_dimension * spatial_dimension;
this->stress_dev .initialize(stress_size);
this->history_integral .initialize(stress_size);
this->dissipated_energy.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
updateInternalParameters();
MaterialElastic<spatial_dimension>::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::updateInternalParameters() {
MaterialElastic<spatial_dimension>::updateInternalParameters();
E_inf = this->E - this->Ev;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::setToSteadyState(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
Array<Real>::matrix_iterator stress_d = stress_dev_vect.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator history_int = history_int_vect.begin(spatial_dimension, spatial_dimension);
/// Loop on all quadrature points
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & dev_s = *stress_d;
Matrix<Real> & h = *history_int;
/// Compute the first invariant of strain
Real Theta = grad_u.trace();
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j) {
dev_s(i, j) = 2 * this->mu * (.5 * (grad_u(i,j) + grad_u(j,i)) - 1./3. * Theta *(i == j));
h(i, j) = 0.;
}
/// Save the deviator of stress
++stress_d;
++history_int;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real tau = 0.;
// if(std::abs(Ev) > std::numeric_limits<Real>::epsilon())
tau = eta / Ev;
Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
Array<Real>::matrix_iterator stress_d = stress_dev_vect.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator history_int = history_int_vect.begin(spatial_dimension, spatial_dimension);
Matrix<Real> s(spatial_dimension, spatial_dimension);
Real dt = this->model->getTimeStep();
Real exp_dt_tau = exp( -dt/tau );
Real exp_dt_tau_2 = exp( -.5*dt/tau );
Matrix<Real> epsilon_d(spatial_dimension, spatial_dimension);
Matrix<Real> epsilon_v(spatial_dimension, spatial_dimension);
/// Loop on all quadrature points
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & dev_s = *stress_d;
Matrix<Real> & h = *history_int;
s.clear();
sigma.clear();
/// Compute the first invariant of strain
Real gamma_inf = E_inf / this->E;
Real gamma_v = Ev / this->E;
this->template gradUToEpsilon<spatial_dimension>(grad_u, epsilon_d);
Real Theta = epsilon_d.trace();
epsilon_v.eye(Theta / Real(3.));
epsilon_d -= epsilon_v;
Matrix<Real> U_rond_prim(spatial_dimension, spatial_dimension);
U_rond_prim.eye(gamma_inf * this->kpa * Theta);
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j) {
s(i, j) = 2 * this->mu * epsilon_d(i, j);
h(i, j) = exp_dt_tau * h(i, j) + exp_dt_tau_2 * (s(i, j) - dev_s(i, j));
dev_s(i, j) = s(i, j);
sigma(i, j) = U_rond_prim(i,j) + gamma_inf * s(i, j) + gamma_v * h(i, j);
}
/// Save the deviator of stress
++stress_d;
++history_int;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
this->updateDissipatedEnergy(el_type, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::updateDissipatedEnergy(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
// if(ghost_type == _ghost) return 0.;
Real tau = 0.;
tau = eta / Ev;
Real * dis_energy = dissipated_energy(el_type, ghost_type).storage();
Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
Array<Real>::matrix_iterator stress_d = stress_dev_vect.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator history_int = history_int_vect.begin(spatial_dimension, spatial_dimension);
Matrix<Real> q(spatial_dimension, spatial_dimension);
Matrix<Real> q_rate(spatial_dimension, spatial_dimension);
Matrix<Real> epsilon_d(spatial_dimension, spatial_dimension);
Matrix<Real> epsilon_v(spatial_dimension, spatial_dimension);
Real dt = this->model->getTimeStep();
Real gamma_v = Ev / this->E;
Real alpha = 1. / (2. * this->mu * gamma_v);
/// Loop on all quadrature points
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & dev_s = *stress_d;
Matrix<Real> & h = *history_int;
/// Compute the first invariant of strain
this->template gradUToEpsilon<spatial_dimension>(grad_u, epsilon_d);
Real Theta = epsilon_d.trace();
epsilon_v.eye(Theta / Real(3.));
epsilon_d -= epsilon_v;
q.copy(dev_s);
q -= h;
q *= gamma_v;
q_rate.copy(dev_s);
q_rate *= gamma_v;
q_rate -= q;
q_rate /= tau;
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
*dis_energy += (epsilon_d(i, j) - alpha * q(i, j)) * q_rate(i, j) * dt;
/// Save the deviator of stress
++stress_d;
++history_int;
++dis_energy;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getDissipatedEnergy() const {
AKANTU_DEBUG_IN();
Real de = 0.;
const Mesh & mesh = this->model->getFEEngine().getMesh();
/// integrate the dissipated energy for each type of elements
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, _not_ghost);
for(; it != end; ++it) {
de += this->model->getFEEngine().integrate(dissipated_energy(*it, _not_ghost), *it,
_not_ghost, this->element_filter(*it, _not_ghost));
}
AKANTU_DEBUG_OUT();
return de;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getDissipatedEnergy(ElementType type, UInt index) const {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points = this->model->getFEEngine().getNbIntegrationPoints(type);
Array<Real>::const_vector_iterator it = this->dissipated_energy(type, _not_ghost).begin(nb_quadrature_points);
UInt gindex = (this->element_filter(type, _not_ghost))(index);
AKANTU_DEBUG_OUT();
return this->model->getFEEngine().integrate(it[index], type, gindex);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getEnergy(std::string type) {
if(type == "dissipated") return getDissipatedEnergy();
else if(type == "dissipated_sls_deviatoric") return getDissipatedEnergy();
else return MaterialElastic<spatial_dimension>::getEnergy(type);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getEnergy(std::string energy_id, ElementType type, UInt index) {
if(energy_id == "dissipated") return getDissipatedEnergy(type, index);
else if(energy_id == "dissipated_sls_deviatoric") return getDissipatedEnergy(type, index);
else return MaterialElastic<spatial_dimension>::getEnergy(energy_id, type, index);
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialStandardLinearSolidDeviatoric);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
index d73f19ee6..54eb0b7c1 100644
--- a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
+++ b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
@@ -1,136 +1,137 @@
/**
* @file material_standard_linear_solid_deviatoric.hh
*
- * @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
*
- * @date creation: Wed Feb 08 2012
- * @date last modification: Wed Nov 13 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 08 2015
*
* @brief Material Visco-elastic, based on Standard Solid rheological model, see
* [] J.C. Simo, T.J.R. Hughes, "Computational Inelasticity", Springer (1998),
* see Sections 10.2 and 10.3
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material_elastic.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_STANDARD_LINEAR_SOLID_DEVIATORIC_HH__
#define __AKANTU_MATERIAL_STANDARD_LINEAR_SOLID_DEVIATORIC_HH__
__BEGIN_AKANTU__
/**
* Material standard linear solid deviatoric
*
*
* @verbatim
E_\inf
------|\/\/\|------
| |
---| |---
| |
----|\/\/\|--[|----
E_v \eta
@endverbatim
*
* keyword : sls_deviatoric
*
* parameters in the material files :
* - E : Initial Young's modulus @f$ E = E_i + E_v @f$
* - eta : viscosity
* - Ev : stiffness of the viscous element
*/
template<UInt spatial_dimension>
class MaterialStandardLinearSolidDeviatoric : public MaterialElastic<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialStandardLinearSolidDeviatoric(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialStandardLinearSolidDeviatoric() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material computed parameter
void initMaterial();
/// update the internal parameters (for modifiable parameters)
virtual void updateInternalParameters();
/// set material to steady state
void setToSteadyState(ElementType el_type, GhostType ghost_type = _not_ghost);
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
protected:
/// update the dissipated energy, is called after the stress have been computed
void updateDissipatedEnergy(ElementType el_type, GhostType ghost_type);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// give the dissipated energy for the time step
Real getDissipatedEnergy() const;
Real getDissipatedEnergy(ElementType type, UInt index) const;
/// get the energy using an energy type string for the time step
virtual Real getEnergy(std::string type);
virtual Real getEnergy(std::string energy_id, ElementType type, UInt index);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// viscosity, viscous elastic modulus
Real eta, Ev, E_inf;
/// history of deviatoric stress
InternalField<Real> stress_dev;
/// Internal variable: history integral
InternalField<Real> history_integral;
/// Dissipated energy
InternalField<Real> dissipated_energy;
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_STANDARD_LINEAR_SOLID_DEVIATORIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
index aca90d1ed..3a339a1a5 100644
--- a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
+++ b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
@@ -1,98 +1,98 @@
/**
* @file plane_stress_toolbox.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 16 2014
- * @date last modification: Tue Sep 16 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief Tools to implement the plane stress behavior in a material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PLANE_STRESS_TOOLBOX_HH__
#define __AKANTU_PLANE_STRESS_TOOLBOX_HH__
__BEGIN_AKANTU__
/**
* Empty class in dimensions different from 2
* This class is only specialized for 2D in the tmpl file
*/
template<UInt dim, class ParentMaterial = Material>
class PlaneStressToolbox : public ParentMaterial {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PlaneStressToolbox(SolidMechanicsModel & model, const ID & id = "") : Material(model, id),
ParentMaterial(model, id) {}
PlaneStressToolbox(SolidMechanicsModel & model,
UInt spatial_dimension,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id = "") : Material(model, spatial_dimension, mesh, fe_engine, id),
ParentMaterial(model, spatial_dimension, mesh, fe_engine, id) {}
virtual ~PlaneStressToolbox() {}
protected:
void initialize();
public:
virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost){
AKANTU_DEBUG_IN();
ParentMaterial::computeAllCauchyStresses(ghost_type);
AKANTU_DEBUG_OUT();
}
virtual void computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ERROR("The function \"computeCauchyStressPlaneStress\" can only be used in 2D Plane stress problems, which means that you made a mistake somewhere!! ");
AKANTU_DEBUG_OUT();
}
protected:
bool initialize_third_axis_deformation;
};
#define AKANTU_PLANE_STRESS_TOOL_SPEC(dim)\
template<> \
inline PlaneStressToolbox<dim, Material>::PlaneStressToolbox(SolidMechanicsModel & model, \
const ID & id) : \
Material(model, id) {} \
AKANTU_PLANE_STRESS_TOOL_SPEC(1)
AKANTU_PLANE_STRESS_TOOL_SPEC(3)
__END_AKANTU__
#include "plane_stress_toolbox_tmpl.hh"
#endif /* __AKANTU_PLANE_STRESS_TOOLBOX_HH__ */
diff --git a/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh b/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
index 5b20c9eda..d9a96b4eb 100644
--- a/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
+++ b/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
@@ -1,171 +1,171 @@
/**
* @file plane_stress_toolbox_tmpl.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Tue Sep 16 2014
- * @date last modification: Tue Sep 16 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief 2D specialization of the akantu::PlaneStressToolbox class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PLANE_STRESS_TOOLBOX_TMPL_HH__
#define __AKANTU_PLANE_STRESS_TOOLBOX_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<class ParentMaterial>
class PlaneStressToolbox<2, ParentMaterial> : public ParentMaterial {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PlaneStressToolbox(SolidMechanicsModel & model, const ID & id = "");
PlaneStressToolbox(SolidMechanicsModel & model,
UInt dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id = "");
virtual ~PlaneStressToolbox() {}
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ThirdAxisDeformation, third_axis_deformation, Real);
protected:
void initialize() {
this->registerParam("Plane_Stress", plane_stress, false, _pat_parsmod, "Is plane stress");
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
virtual void initMaterial() {
ParentMaterial::initMaterial();
if(this->plane_stress && this->initialize_third_axis_deformation){
this->third_axis_deformation.initialize(1);
this->third_axis_deformation.resize();
}
}
/* ------------------------------------------------------------------------ */
virtual void computeStress(ElementType el_type, GhostType ghost_type) {
ParentMaterial::computeStress(el_type, ghost_type);
if(this->plane_stress) computeThirdAxisDeformation(el_type, ghost_type);
}
/* ------------------------------------------------------------------------ */
virtual void computeThirdAxisDeformation(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type) {
}
/// Computation of Cauchy stress tensor in the case of finite deformation
virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost){
AKANTU_DEBUG_IN();
if(this->plane_stress){
AKANTU_DEBUG_ASSERT(this->finite_deformation,"The Cauchy stress can only be computed if you are working in finite deformation.");
//resizeInternalArray(stress);
Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(2, ghost_type);
Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(2, ghost_type);
for(; it != last_type; ++it)
this->computeCauchyStressPlaneStress(*it, ghost_type);
}
else
ParentMaterial::computeAllCauchyStresses(ghost_type);
AKANTU_DEBUG_OUT();
}
virtual void computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type = _not_ghost){};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// third axis strain measure value
InternalField<Real> third_axis_deformation;
/// Plane stress or plane strain
bool plane_stress;
/// For non linear materials, the \epsilon_{zz} might be required
bool initialize_third_axis_deformation;
};
template<class ParentMaterial>
inline PlaneStressToolbox<2, ParentMaterial>::PlaneStressToolbox(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
ParentMaterial(model, id),
third_axis_deformation("third_axis_deformation", *this),
plane_stress(false),
initialize_third_axis_deformation(false) {
/// @todo Plane_Stress should not be possible to be modified after initMaterial (but before)
this->initialize();
}
template<class ParentMaterial>
inline PlaneStressToolbox<2, ParentMaterial>::PlaneStressToolbox(SolidMechanicsModel & model,
UInt dim,
const Mesh & mesh,
FEEngine & fe_engine,
const ID & id):
Material(model, dim, mesh, fe_engine, id),
ParentMaterial(model, dim, mesh, fe_engine, id),
third_axis_deformation("third_axis_deformation", *this, dim, fe_engine, this->element_filter),
plane_stress(false),
initialize_third_axis_deformation(false) {
this->initialize();
}
template<>
inline PlaneStressToolbox<2, Material>::PlaneStressToolbox(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
third_axis_deformation("third_axis_deformation", *this),
plane_stress(false),
initialize_third_axis_deformation(false) {
/// @todo Plane_Stress should not be possible to be modified after initMaterial (but before)
this->registerParam("Plane_Stress", plane_stress, false, _pat_parsmod, "Is plane stress");
}
__END_AKANTU__
#endif /* __AKANTU_PLANE_STRESS_TOOLBOX_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/random_internal_field.hh b/src/model/solid_mechanics/materials/random_internal_field.hh
index d22a7a418..595725b9a 100644
--- a/src/model/solid_mechanics/materials/random_internal_field.hh
+++ b/src/model/solid_mechanics/materials/random_internal_field.hh
@@ -1,108 +1,109 @@
/**
* @file random_internal_field.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Jul 29 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Random internal material parameter
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_random_generator.hh"
#include "internal_field.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_RANDOM_INTERNAL_FIELD_HH__
#define __AKANTU_RANDOM_INTERNAL_FIELD_HH__
__BEGIN_AKANTU__
/**
* class for the internal fields of materials with a random
* distribution
*/
template<typename T,
template<typename> class BaseField = InternalField,
template<typename> class Generator = RandGenerator>
class RandomInternalField : public BaseField<T> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
RandomInternalField(const ID & id, Material & material);
virtual ~RandomInternalField();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
private:
RandomInternalField operator=(__attribute__((unused)) const RandomInternalField & other) {};
public:
AKANTU_GET_MACRO(RandomParameter, random_parameter, const RandomParameter<T>);
/// initialize the field to a given number of component
virtual void initialize(UInt nb_component);
/// set the field to a given value
void setDefaultValue(const T & value);
/// set the specified random distribution to a given parameter
void setRandomDistribution(const RandomParameter<T> & param);
/// print the content
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
virtual void setArrayValues(T * begin, T * end);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
inline operator Real() const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// random parameter containing the distribution and base value
RandomParameter<T> random_parameter;
};
/// standard output stream operator
template<typename T>
inline std::ostream & operator <<(std::ostream & stream, const RandomInternalField<T> & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_RANDOM_INTERNAL_FIELD_HH__ */
diff --git a/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh b/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh
index 15c1be9ee..e94fa6602 100644
--- a/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh
@@ -1,125 +1,125 @@
/**
* @file random_internal_field_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Wed Nov 13 2013
+ * @date last modification: Tue Dec 08 2015
*
* @brief Random internal material parameter implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_random_generator.hh"
#include "internal_field_tmpl.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_RANDOM_INTERNAL_FIELD_TMPL_HH__
#define __AKANTU_RANDOM_INTERNAL_FIELD_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
RandomInternalField<T, BaseField, Generator>::RandomInternalField(
const ID & id, Material & material)
: BaseField<T>(id, material), random_parameter(T()) {}
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
RandomInternalField<T, BaseField, Generator>::~RandomInternalField() {}
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::initialize(
UInt nb_component) {
this->internalInitialize(nb_component);
}
/* ------------------------------------------------------------------------ */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::setDefaultValue(
const T & value) {
random_parameter.setBaseValue(value);
this->reset();
}
/* ------------------------------------------------------------------------ */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::setRandomDistribution(
const RandomParameter<T> & param) {
random_parameter = param;
this->reset();
}
/* ------------------------------------------------------------------------ */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::printself(
std::ostream & stream, int indent) const {
stream << "RandomInternalField [ ";
random_parameter.printself(stream);
stream << " ]";
#if !defined(AKANTU_NDEBUG)
if (AKANTU_DEBUG_TEST(dblDump)) {
stream << std::endl;
InternalField<T>::printself(stream, indent);
}
#endif
}
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::setArrayValues(T * begin,
T * end) {
random_parameter.template setValues<Generator>(begin, end);
}
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
inline RandomInternalField<T, BaseField, Generator>::operator Real() const {
return random_parameter.getBaseValue();
}
/* -------------------------------------------------------------------------- */
template <>
inline void ParsableParamTyped<RandomInternalField<Real> >::parseParam(
const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
RandomParameter<Real> r = in_param;
param.setRandomDistribution(r);
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_RANDOM_INTERNAL_FIELD_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/base_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/base_weight_function.hh
index 37da662d7..a47b5c7d2 100644
--- a/src/model/solid_mechanics/materials/weight_functions/base_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/base_weight_function.hh
@@ -1,183 +1,183 @@
/**
* @file base_weight_function.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Thu Oct 15 2015
*
- * @brief Base weight function for non local materials
+ * @brief Base weight function for non local materials
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_types.hh"
#include "parsable.hh"
#include <cmath>
#if defined(AKANTU_DEBUG_TOOLS)
#include "aka_debug_tools.hh"
#include <string>
#endif
#include "non_local_manager.hh"
/* -------------------------------------------------------------------------- */
#include <vector>
#include "material_damage.hh"
#ifndef __AKANTU_BASE_WEIGHT_FUNCTION_HH__
#define __AKANTU_BASE_WEIGHT_FUNCTION_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Normal weight function */
/* -------------------------------------------------------------------------- */
class BaseWeightFunction : public Parsable {
public:
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
BaseWeightFunction(NonLocalManager & manager, const std::string & type = "base") :
Parsable(_st_weight_function, "weight_function:" + type),
manager(manager),
type(type),
spatial_dimension(manager.getModel().getSpatialDimension()) {
this->registerParam("update_rate" , update_rate, 1U ,
_pat_parsmod, "Update frequency");
}
virtual ~BaseWeightFunction() {}
/* -------------------------------------------------------------------------- */
/* Methods */
/* -------------------------------------------------------------------------- */
/// initialize the weight function
virtual inline void init();
/// update the internal parameters
virtual void updateInternals() {};
/* ------------------------------------------------------------------------ */
/// set the non-local radius
inline void setRadius(Real radius);
/* ------------------------------------------------------------------------ */
/// compute the weight for a given distance between two quadrature points
inline Real operator()(Real r,
const __attribute__((unused)) IntegrationPoint & q1,
const __attribute__((unused)) IntegrationPoint & q2);
/// print function
void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "WeightFunction " << type << " [" << std::endl;
Parsable::printself(stream, indent);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
/* Accessors */
/* -------------------------------------------------------------------------- */
public:
/// get the radius
Real getRadius() { return R; }
/// get the update rate
UInt getUpdateRate() { return update_rate; }
public:
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
virtual UInt getNbDataForElements(__attribute__((unused)) const Array<Element> & elements,
__attribute__((unused)) SynchronizationTag tag) const {
return 0;
}
virtual inline void packElementData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const Array<Element> & elements,
__attribute__((unused)) SynchronizationTag tag) const {}
virtual inline void unpackElementData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const Array<Element> & elements,
__attribute__((unused)) SynchronizationTag tag) {}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Type, type, const ID &);
protected:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// reference to the non-local manager
NonLocalManager & manager;
/// the non-local radius
Real R;
/// the non-local radius squared
Real R2;
/// the update rate
UInt update_rate;
/// name of the type of weight function
const std::string type;
/// the spatial dimension
UInt spatial_dimension;
};
inline std::ostream & operator <<(std::ostream & stream,
const BaseWeightFunction & _this)
{
_this.printself(stream);
return stream;
}
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "base_weight_function_inline_impl.cc"
#endif
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* Include all other weight function types */
/* -------------------------------------------------------------------------- */
# include "damaged_weight_function.hh"
# include "remove_damaged_weight_function.hh"
# include "remove_damaged_with_damage_rate_weight_function.hh"
# include "stress_based_weight_function.hh"
/* -------------------------------------------------------------------------- */
#endif /* __AKANTU_BASE_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/base_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/base_weight_function_inline_impl.cc
index 572cff38b..68d782e10 100644
--- a/src/model/solid_mechanics/materials/weight_functions/base_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/base_weight_function_inline_impl.cc
@@ -1,58 +1,58 @@
/**
- * @file base_weight_function_inline_impl.hh
+ * @file base_weight_function_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Thu Oct 15 2015
*
- * @brief Implementation of inline function of base weight function
+ * @brief Implementation of inline function of base weight function
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
inline void BaseWeightFunction::init() {
/// compute R^2 for a given non-local radius
this->R2 = this->R *this-> R;
}
/* -------------------------------------------------------------------------- */
inline void BaseWeightFunction::setRadius(Real radius) {
/// set the non-local radius and update R^2 accordingly
this->R = radius;
this->R2 = this->R * this->R;
}
/* -------------------------------------------------------------------------- */
inline Real BaseWeightFunction:: operator()(Real r,
const __attribute__((unused)) IntegrationPoint & q1,
const __attribute__((unused)) IntegrationPoint & q2) {
/// initialize the weight
Real w = 0;
/// compute weight for given r
if(r <= this->R) {
Real alpha = (1. - r*r / this->R2);
w = alpha * alpha;
// *weight = 1 - sqrt(r / radius);
}
return w;
}
diff --git a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
index 0145a6680..d0e3473c2 100644
--- a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
@@ -1,82 +1,83 @@
/**
* @file damaged_weight_function.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief Damaged weight function for non local materials
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "base_weight_function.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DAMAGED_WEIGHT_FUNCTION_HH__
#define __AKANTU_DAMAGED_WEIGHT_FUNCTION_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Damage weight function */
/* -------------------------------------------------------------------------- */
class DamagedWeightFunction : public BaseWeightFunction {
public:
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
DamagedWeightFunction(NonLocalManager & manager) : BaseWeightFunction(manager, "damaged"),
damage(NULL) {
this->init();
}
/* -------------------------------------------------------------------------- */
/* Base Weight Function inherited methods */
/* -------------------------------------------------------------------------- */
/// set the pointers of internals to the right flattend version
virtual void init();
inline Real operator()(Real r,
const __attribute__((unused)) IntegrationPoint & q1,
const IntegrationPoint & q2);
private:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// internal pointer to the current damage vector
ElementTypeMapReal * damage;
};
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "damaged_weight_function_inline_impl.cc"
#endif
__END_AKANTU__
#endif /* __AKANTU_DAMAGED_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
index a2ccd6915..0c81aecfa 100644
--- a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
@@ -1,74 +1,74 @@
/**
- * @file damaged_weight_function_inline_impl.hh
+ * @file damaged_weight_function_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Thu Oct 15 2015
*
- * @brief Implementation of inline function of damaged weight function
+ * @brief Implementation of inline function of damaged weight function
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
inline Real DamagedWeightFunction::operator()(Real r,
const __attribute__((unused)) IntegrationPoint & q1,
const IntegrationPoint & q2) {
/// compute the weight
UInt quad = q2.global_num;
Array<Real> & dam_array = (*this->damage)(q2.type, q2.ghost_type);
Real D = dam_array(quad);
Real Radius_t = 0;
Real Radius_init = this->R2;
// if(D <= 0.5)
// {
// Radius_t = 2*D*Radius_init;
// }
// else
// {
// Radius_t = 2*Radius_init*(1-D);
// }
//
Radius_t = Radius_init*(1-D);
Radius_init *= Radius_init;
Radius_t *= Radius_t;
if(Radius_t < Math::getTolerance()) {
Radius_t = 0.001*Radius_init;
}
Real expb = (2*std::log(0.51))/(std::log(1.0-0.49*Radius_t/Radius_init));
Int expb_floor=std::floor(expb);
Real b = expb_floor + expb_floor%2;
Real alpha = std::max(0., 1. - r*r / Radius_init);
Real w = std::pow(alpha,b);
return w;
}
/* -------------------------------------------------------------------------- */
inline void DamagedWeightFunction::init() {
this->damage = &(this->manager.registerWeightFunctionInternal("damage"));
}
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
index ea30b36ec..f969ba02c 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
@@ -1,100 +1,99 @@
-
/**
* @file remove_damaged_weight_function.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Thu Oct 15 2015
*
* @brief Removed damaged weight function for non local materials
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "base_weight_function.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_REMOVE_DAMAGED_WEIGHT_FUNCTION_HH__
#define __AKANTU_REMOVE_DAMAGED_WEIGHT_FUNCTION_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Remove damaged weight function */
/* -------------------------------------------------------------------------- */
class RemoveDamagedWeightFunction : public BaseWeightFunction {
public:
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
RemoveDamagedWeightFunction(NonLocalManager & manager) : BaseWeightFunction(manager, "remove_damaged"),
damage(NULL){
this->registerParam("damage_limit", this->damage_limit, 1., _pat_parsable, "Damage Threshold");
this->init();
}
/* -------------------------------------------------------------------------- */
/* Base Weight Function inherited methods */
/* -------------------------------------------------------------------------- */
virtual inline void init();
inline Real operator()(Real r,
const __attribute__((unused)) IntegrationPoint & q1,
const IntegrationPoint & q2);
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
private:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// limit at which a point is considered as complitely broken
Real damage_limit;
/// internal pointer to the current damage vector
ElementTypeMapReal * damage;
};
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "remove_damaged_weight_function_inline_impl.cc"
#endif
__END_AKANTU__
#endif /* __AKANTU_REMOVE_DAMAGED_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc
index e9d5d883a..6616daafc 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc
@@ -1,86 +1,86 @@
/**
- * @file remove_damaged_weight_function_inline_impl.hh
+ * @file remove_damaged_weight_function_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Wed Oct 21 2015
*
- * @brief Implementation of inline function of remove damaged weight function
+ * @brief Implementation of inline function of remove damaged weight function
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
inline Real RemoveDamagedWeightFunction::operator()(Real r,
const __attribute__((unused)) IntegrationPoint & q1,
const IntegrationPoint & q2) {
/// compute the weight
UInt quad = q2.global_num;
if(q1 == q2) return 1.;
Array<Real> & dam_array = (*this->damage)(q2.type, q2.ghost_type);
Real D = dam_array(quad);
Real w = 0.;
if (D < damage_limit * (1 - Math::getTolerance())) {
Real alpha = std::max(0., 1. - r*r / this->R2);
w = alpha * alpha;
}
return w;
}
/* -------------------------------------------------------------------------- */
inline void RemoveDamagedWeightFunction::init() {
this->damage = &(this->manager.registerWeightFunctionInternal("damage"));
}
/* -------------------------------------------------------------------------- */
inline UInt RemoveDamagedWeightFunction::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
if(tag == _gst_mnl_weight)
return this->manager.getModel().getNbIntegrationPoints(elements) * sizeof(Real);
return 0;
}
/* -------------------------------------------------------------------------- */
inline void RemoveDamagedWeightFunction::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
if(tag == _gst_mnl_weight) {
DataAccessor::packElementalDataHelper<Real>(*damage, buffer, elements, true, this->manager.getModel().getFEEngine());
}
}
/* -------------------------------------------------------------------------- */
inline void RemoveDamagedWeightFunction::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
if(tag == _gst_mnl_weight) {
DataAccessor::unpackElementalDataHelper<Real>(*damage, buffer, elements, true, this->manager.getModel().getFEEngine());
}
}
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
index 46e274113..a959aa1ab 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
@@ -1,81 +1,82 @@
/**
- * @file remove_damaged_with damage_rate_weight_function.hh
+ * @file remove_damaged_with_damage_rate_weight_function.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief Removed damaged weight function for non local materials
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "base_weight_function.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_REMOVE_DAMAGED_WITH_DAMAGE_RATE_WEIGHT_FUNCTION_HH__
#define __AKANTU_REMOVE_DAMAGED_WITH_DAMAGE_RATE_WEIGHT_FUNCTION_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Remove damaged with damage rate weight function */
/* -------------------------------------------------------------------------- */
class RemoveDamagedWithDamageRateWeightFunction : public BaseWeightFunction {
public:
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
RemoveDamagedWithDamageRateWeightFunction(NonLocalManager & manager) : BaseWeightFunction(manager, "remove_damage_with_damage_rate"),
damage_with_damage_rate(NULL) {
this->registerParam<Real>("damage_limit", this->damage_limit_with_damage_rate, 1, _pat_parsable, "Damage Threshold");
this->init();
}
/* -------------------------------------------------------------------------- */
/* Base Weight Function inherited methods */
/* -------------------------------------------------------------------------- */
inline Real operator()(Real r,
const __attribute__((unused)) IntegrationPoint & q1,
const IntegrationPoint & q2);
virtual inline void init();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// limit at which a point is considered as complitely broken
Real damage_limit_with_damage_rate;
/// internal pointer to the current damage vector
ElementTypeMapReal * damage_with_damage_rate;
};
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "remove_damaged_with_damage_rate_weight_function_inline_impl.cc"
#endif
__END_AKANTU__
#endif /* __AKANTU_REMOVE_DAMAGED_WITH_DAMAGE_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
index f2442933d..918813435 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
@@ -1,60 +1,60 @@
/**
- * @file remove_damaged_with damage_rate_weight_function_inline_impl.cc
+ * @file remove_damaged_with_damage_rate_weight_function_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Thu Oct 15 2015
*
- * @brief Implementation of inline function of remove damaged with
+ * @brief Implementation of inline function of remove damaged with
* damage rate weight function
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
inline void RemoveDamagedWithDamageRateWeightFunction::init() {
this->damage_with_damage_rate = &(this->manager.registerWeightFunctionInternal("damage-rate"));
}
/* -------------------------------------------------------------------------- */
inline Real RemoveDamagedWithDamageRateWeightFunction::operator()(Real r,
const __attribute__((unused)) IntegrationPoint & q1,
const IntegrationPoint & q2) {
/// compute the weight
UInt quad = q2.global_num;
if(q1.global_num == quad) return 1.;
Array<Real> & dam_array = (*this->damage_with_damage_rate)(q2.type, q2.ghost_type);
Real D = dam_array(quad);
Real w = 0.;
Real alphaexp = 1.;
Real betaexp = 2.;
if(D < damage_limit_with_damage_rate) {
Real alpha = std::max(0., 1. - pow((r*r / this->R2),alphaexp));
w = pow(alpha, betaexp);
}
return w;
}
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
index 0f475c808..233d87cee 100644
--- a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
@@ -1,116 +1,117 @@
/**
* @file stress_based_weight_function.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Wed Oct 07 2015
*
* @brief implementation of the stres based weight function classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
+
/* -------------------------------------------------------------------------- */
#include "stress_based_weight_function.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
StressBasedWeightFunction::StressBasedWeightFunction(NonLocalManager & manager) :
BaseWeightFunction(manager, "stress_based")
// stress_diag("stress_diag", material), selected_stress_diag(NULL),
// stress_base("stress_base", material), selected_stress_base(NULL),
// characteristic_size("lc", material), selected_characteristic_size(NULL)
{
// this->registerParam("ft", this->ft, 0., _pat_parsable, "Tensile strength");
// stress_diag.initialize(spatial_dimension);
// stress_base.initialize(spatial_dimension * spatial_dimension);
// characteristic_size.initialize(1);
}
/* -------------------------------------------------------------------------- */
/// During intialization the characteristic sizes for all quadrature
/// points are computed
void StressBasedWeightFunction::init() {
// const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
// for (UInt g = _not_ghost; g <= _ghost; ++g) {
// GhostType gt = GhostType(g);
// Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt);
// Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt);
// for(; it != last_type; ++it) {
// UInt nb_quadrature_points =
// this->material.getModel().getFEEngine().getNbQuadraturePoints(*it, gt);
// const Array<UInt> & element_filter = this->material.getElementFilter(*it, gt);
// UInt nb_element = element_filter.getSize();
// Array<Real> ones(nb_element*nb_quadrature_points, 1, 1.);
// Array<Real> & lc = characteristic_size(*it, gt);
// this->material.getModel().getFEEngine().integrateOnQuadraturePoints(ones,
// lc,
// 1,
// *it,
// gt,
// element_filter);
// for (UInt q = 0; q < nb_quadrature_points * nb_element; q++) {
// lc(q) = pow(lc(q), 1./ Real(spatial_dimension));
// }
// }
// }
}
/* -------------------------------------------------------------------------- */
/// computation of principals stresses and principal directions
void StressBasedWeightFunction::updatePrincipalStress(GhostType ghost_type) {
// AKANTU_DEBUG_IN();
// const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
// Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
// Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
// for(; it != last_type; ++it) {
// Array<Real>::const_matrix_iterator sigma =
// this->material.getStress(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
// Array<Real>::vector_iterator eigenvalues =
// stress_diag(*it, ghost_type).begin(spatial_dimension);
// Array<Real>::vector_iterator eigenvalues_end =
// stress_diag(*it, ghost_type).end(spatial_dimension);
// Array<Real>::matrix_iterator eigenvector =
// stress_base(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
// #ifndef __trick__
// Array<Real>::iterator<Real> cl = characteristic_size(*it, ghost_type).begin();
// #endif
// UInt q = 0;
// for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues, ++eigenvector, ++cl, ++q) {
// sigma->eig(*eigenvalues, *eigenvector);
// *eigenvalues /= ft;
// #ifndef __trick__
// // specify a lower bound for principal stress based on the size of the element
// for (UInt i = 0; i < spatial_dimension; ++i) {
// (*eigenvalues)(i) = std::max(*cl / this->R, (*eigenvalues)(i));
// }
// #endif
// }
// }
// AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
index 8d2f12c91..56593df10 100644
--- a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
@@ -1,104 +1,104 @@
/**
* @file stress_based_weight_function.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Thu Oct 15 2015
*
* @brief Removed damaged weight function for non local materials
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "base_weight_function.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STRESS_BASED_WEIGHT_FUNCTION_HH__
#define __AKANTU_STRESS_BASED_WEIGHT_FUNCTION_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Stress Based Weight */
/* -------------------------------------------------------------------------- */
/// based on based on Giry et al.: Stress-based nonlocal damage model,
/// IJSS, 48, 2011
class StressBasedWeightFunction : public BaseWeightFunction {
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
StressBasedWeightFunction(NonLocalManager & manager);
/* -------------------------------------------------------------------------- */
/* Base Weight Function inherited methods */
/* -------------------------------------------------------------------------- */
void init();
virtual inline void updateInternals();
void updatePrincipalStress(GhostType ghost_type);
inline void updateQuadraturePointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates);
inline Real operator()(Real r,
const IntegrationPoint & q1,
const IntegrationPoint & q2);
/// computation of ellipsoid
inline Real computeRhoSquare(Real r,
Vector<Real> & eigs,
Matrix<Real> & eigenvects,
Vector<Real> & x_s);
protected:
inline void setInternal();
private:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// tensile strength
Real ft;
/// prinicipal stresses
ElementTypeMapReal * stress_diag;
/// for preselection of types (optimization)
ElementTypeMapReal * selected_stress_diag;
/// principal directions
ElementTypeMapReal * stress_base;
/// lenght intrinisic to the material
ElementTypeMapReal * characteristic_size;
};
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "stress_based_weight_function_inline_impl.cc"
#endif
__END_AKANTU__
#endif /* __AKANTU_STRESS_BASED_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
index 9a4cc5e89..a05e9c467 100644
--- a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
@@ -1,189 +1,190 @@
/**
* @file stress_based_weight_function_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
* @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Thu Oct 15 2015
*
- * @brief Implementation of inline function of remove damaged with
+ * @brief Implementation of inline function of remove damaged with
* damage rate weight function
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline void StressBasedWeightFunction::updateInternals() {
// updatePrincipalStress(_not_ghost);
// updatePrincipalStress(_ghost);
}
/* -------------------------------------------------------------------------- */
// inline void StressBasedWeightFunction::selectType(ElementType type1,
// GhostType ghost_type1,
// ElementType type2,
// GhostType ghost_type2) {
// selected_stress_diag = &stress_diag(type2, ghost_type2);
// selected_stress_base = &stress_base(type2, ghost_type2);
// selected_characteristic_size = &characteristic_size(type1, ghost_type1);
// }
/* -------------------------------------------------------------------------- */
inline Real StressBasedWeightFunction::computeRhoSquare(Real r,
Vector<Real> & eigs,
Matrix<Real> & eigenvects,
Vector<Real> & x_s) {
// if (spatial_dimension == 1)
// return eigs[0];
// else if (spatial_dimension == 2) {
// Vector<Real> u1(eigenvects.storage(), 2);
// Real cos_t = x_s.dot(u1) / (x_s.norm() * u1.norm());
// Real cos_t_2;
// Real sin_t_2;
// Real sigma1_2 = eigs[0]*eigs[0];
// Real sigma2_2 = eigs[1]*eigs[1];
// #ifdef __trick__
// Real zero = std::numeric_limits<Real>::epsilon();
// if(std::abs(cos_t) < zero) {
// cos_t_2 = 0;
// sin_t_2 = 1;
// } else {
// cos_t_2 = cos_t * cos_t;
// sin_t_2 = (1 - cos_t_2);
// }
// Real rhop1 = std::max(0., cos_t_2 / sigma1_2);
// Real rhop2 = std::max(0., sin_t_2 / sigma2_2);
// #else
// cos_t_2 = cos_t * cos_t;
// sin_t_2 = (1 - cos_t_2);
// Real rhop1 = cos_t_2 / sigma1_2;
// Real rhop2 = sin_t_2 / sigma2_2;
// #endif
// return 1./ (rhop1 + rhop2);
// } else if (spatial_dimension == 3) {
// Vector<Real> u1(eigenvects.storage() + 0*3, 3);
// //Vector<Real> u2(eigenvects.storage() + 1*3, 3);
// Vector<Real> u3(eigenvects.storage() + 2*3, 3);
// Real zero = std::numeric_limits<Real>::epsilon();
// Vector<Real> tmp(3);
// tmp.crossProduct(x_s, u3);
// Vector<Real> u3_C_x_s_C_u3(3);
// u3_C_x_s_C_u3.crossProduct(u3, tmp);
// Real norm_u3_C_x_s_C_u3 = u3_C_x_s_C_u3.norm();
// Real cos_t = 0.;
// if(std::abs(norm_u3_C_x_s_C_u3) > zero) {
// Real inv_norm_u3_C_x_s_C_u3 = 1. / norm_u3_C_x_s_C_u3;
// cos_t = u1.dot(u3_C_x_s_C_u3) * inv_norm_u3_C_x_s_C_u3;
// }
// Real cos_p = u3.dot(x_s) / r;
// Real cos_t_2;
// Real sin_t_2;
// Real cos_p_2;
// Real sin_p_2;
// Real sigma1_2 = eigs[0]*eigs[0];
// Real sigma2_2 = eigs[1]*eigs[1];
// Real sigma3_2 = eigs[2]*eigs[2];
// #ifdef __trick__
// if(std::abs(cos_t) < zero) {
// cos_t_2 = 0;
// sin_t_2 = 1;
// } else {
// cos_t_2 = cos_t * cos_t;
// sin_t_2 = (1 - cos_t_2);
// }
// if(std::abs(cos_p) < zero) {
// cos_p_2 = 0;
// sin_p_2 = 1;
// } else {
// cos_p_2 = cos_p * cos_p;
// sin_p_2 = (1 - cos_p_2);
// }
// Real rhop1 = std::max(0., sin_p_2 * cos_t_2 / sigma1_2);
// Real rhop2 = std::max(0., sin_p_2 * sin_t_2 / sigma2_2);
// Real rhop3 = std::max(0., cos_p_2 / sigma3_2);
// #else
// cos_t_2 = cos_t * cos_t;
// sin_t_2 = (1 - cos_t_2);
// cos_p_2 = cos_p * cos_p;
// sin_p_2 = (1 - cos_p_2);
// Real rhop1 = sin_p_2 * cos_t_2 / sigma1_2;
// Real rhop2 = sin_p_2 * sin_t_2 / sigma2_2;
// Real rhop3 = cos_p_2 / sigma3_2;
// #endif
// return 1./ (rhop1 + rhop2 + rhop3);
// }
return 0.;
}
/* -------------------------------------------------------------------------- */
inline Real StressBasedWeightFunction::operator()(Real r,
const IntegrationPoint & q1,
const IntegrationPoint & q2) {
// Real zero = std::numeric_limits<Real>::epsilon();
// if(r < zero) return 1.; // means x and s are the same points
// const Vector<Real> & x = q1.getPosition();
// const Vector<Real> & s = q2.getPosition();
// Vector<Real> eigs =
// selected_stress_diag->begin(spatial_dimension)[q2.global_num];
// Matrix<Real> eigenvects =
// selected_stress_base->begin(spatial_dimension, spatial_dimension)[q2.global_num];
// Real min_rho_lc = selected_characteristic_size->begin()[q1.global_num];
// Vector<Real> x_s(spatial_dimension);
// x_s = x;
// x_s -= s;
// Real rho_2 = computeRhoSquare(r, eigs, eigenvects, x_s);
// Real rho_lc_2 = std::max(this->R2 * rho_2, min_rho_lc*min_rho_lc);
// // Real w = std::max(0., 1. - r*r / rho_lc_2);
// // w = w*w;
// Real w = exp(- 2*2*r*r / rho_lc_2);
// return w;
return 0.;
}
diff --git a/src/model/solid_mechanics/solid_mechanics_model.cc b/src/model/solid_mechanics/solid_mechanics_model.cc
index 9efc3c880..f27300a57 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model.cc
@@ -1,1832 +1,1836 @@
/**
* @file solid_mechanics_model.cc
*
+ * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author David Simon Kammer <david.kammer@epfl.ch>
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Jul 27 2010
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Mon Nov 30 2015
*
* @brief Implementation of the SolidMechanicsModel class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_math.hh"
#include "aka_common.hh"
#include "solid_mechanics_model.hh"
#include "group_manager_inline_impl.cc"
#include "dumpable_inline_impl.hh"
#include "integration_scheme_2nd_order.hh"
#include "element_group.hh"
#include "static_communicator.hh"
#include "dof_synchronizer.hh"
#include "element_group.hh"
#include <cmath>
#ifdef AKANTU_USE_MUMPS
#include "solver_mumps.hh"
#endif
#ifdef AKANTU_USE_PETSC
#include "solver_petsc.hh"
#include "petsc_matrix.hh"
#endif
#ifdef AKANTU_USE_IOHELPER
# include "dumper_field.hh"
# include "dumper_paraview.hh"
# include "dumper_homogenizing_field.hh"
# include "dumper_internal_material_field.hh"
# include "dumper_elemental_field.hh"
# include "dumper_material_padders.hh"
# include "dumper_element_partition.hh"
# include "dumper_iohelper.hh"
#endif
#ifdef AKANTU_DAMAGE_NON_LOCAL
# include "non_local_manager.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const SolidMechanicsModelOptions default_solid_mechanics_model_options(_explicit_lumped_mass, false);
/* -------------------------------------------------------------------------- */
/**
* A solid mechanics model need a mesh and a dimension to be created. the model
* by it self can not do a lot, the good init functions should be called in
* order to configure the model depending on what we want to do.
*
* @param mesh mesh representing the model we want to simulate
* @param dim spatial dimension of the problem, if dim = 0 (default value) the
* dimension of the problem is assumed to be the on of the mesh
* @param id an id to identify the model
*/
SolidMechanicsModel::SolidMechanicsModel(Mesh & mesh,
UInt dim,
const ID & id,
const MemoryID & memory_id) :
Model(mesh, dim, id, memory_id),
BoundaryCondition<SolidMechanicsModel>(),
time_step(NAN), f_m2a(1.0),
mass_matrix(NULL),
velocity_damping_matrix(NULL),
stiffness_matrix(NULL),
jacobian_matrix(NULL),
material_index("material index", id),
material_local_numbering("material local numbering", id),
material_selector(new DefaultMaterialSelector(material_index)),
is_default_material_selector(true),
integrator(NULL),
increment_flag(false), solver(NULL),
synch_parallel(NULL),
are_materials_instantiated(false),
non_local_manager(NULL),
pbc_synch(NULL) {
AKANTU_DEBUG_IN();
createSynchronizerRegistry(this);
registerFEEngineObject<MyFEEngineType>("SolidMechanicsFEEngine", mesh, spatial_dimension);
this->displacement = NULL;
this->mass = NULL;
this->velocity = NULL;
this->acceleration = NULL;
this->force = NULL;
this->residual = NULL;
this->blocked_dofs = NULL;
this->increment = NULL;
this->increment_acceleration = NULL;
this->dof_synchronizer = NULL;
this->previous_displacement = NULL;
materials.clear();
mesh.registerEventHandler(*this);
#if defined(AKANTU_USE_IOHELPER)
this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_regular);
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SolidMechanicsModel::~SolidMechanicsModel() {
AKANTU_DEBUG_IN();
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
delete *mat_it;
}
materials.clear();
delete integrator;
delete solver;
delete mass_matrix;
delete velocity_damping_matrix;
if(stiffness_matrix && stiffness_matrix != jacobian_matrix)
delete stiffness_matrix;
delete jacobian_matrix;
delete synch_parallel;
if(is_default_material_selector) {
delete material_selector;
material_selector = NULL;
}
#ifdef AKANTU_DAMAGE_NON_LOCAL
delete non_local_manager;
non_local_manager = NULL;
#endif
delete pbc_synch;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::setTimeStep(Real time_step) {
this->time_step = time_step;
#if defined(AKANTU_USE_IOHELPER)
this->mesh.getDumper().setTimeStep(time_step);
#endif
}
/* -------------------------------------------------------------------------- */
/* Initialisation */
/* -------------------------------------------------------------------------- */
/**
* This function groups many of the initialization in on function. For most of
* basics case the function should be enough. The functions initialize the
* model, the internal vectors, set them to 0, and depending on the parameters
* it also initialize the explicit or implicit solver.
*
* @param material_file the file containing the materials to use
* @param method the analysis method wanted. See the akantu::AnalysisMethod for
* the different possibilities
*/
void SolidMechanicsModel::initFull(const ModelOptions & options) {
Model::initFull(options);
const SolidMechanicsModelOptions & smm_options =
dynamic_cast<const SolidMechanicsModelOptions &>(options);
this->method = smm_options.analysis_method;
// initialize the vectors
this->initArrays();
// set the initial condition to 0
this->force->clear();
this->velocity->clear();
this->acceleration->clear();
this->displacement->clear();
// initialize pbc
if(this->pbc_pair.size()!=0)
this->initPBC();
// initialize the time integration schemes
switch(this->method) {
case _explicit_lumped_mass:
this->initExplicit();
break;
case _explicit_consistent_mass:
this->initSolver();
this->initExplicit();
break;
case _implicit_dynamic:
this->initImplicit(true);
break;
case _static:
this->initImplicit(false);
this->initArraysPreviousDisplacment();
break;
default:
AKANTU_EXCEPTION("analysis method not recognised by SolidMechanicsModel");
break;
}
#ifdef AKANTU_DAMAGE_NON_LOCAL
/// create the non-local manager object for non-local damage computations
this->non_local_manager = new NonLocalManager(*this);
#endif
// initialize the materials
if(this->parser->getLastParsedFile() != "") {
this->instantiateMaterials();
}
if(!smm_options.no_init_materials) {
this->initMaterials();
}
if(this->increment_flag)
this->initBC(*this, *this->displacement, *this->increment, *this->force);
else
this->initBC(*this, *this->displacement, *this->force);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initParallel(MeshPartition * partition,
DataAccessor * data_accessor) {
AKANTU_DEBUG_IN();
if (data_accessor == NULL) data_accessor = this;
synch_parallel = &createParallelSynch(partition,data_accessor);
synch_registry->registerSynchronizer(*synch_parallel, _gst_material_id);
synch_registry->registerSynchronizer(*synch_parallel, _gst_smm_mass);
synch_registry->registerSynchronizer(*synch_parallel, _gst_smm_stress);
synch_registry->registerSynchronizer(*synch_parallel, _gst_smm_boundary);
synch_registry->registerSynchronizer(*synch_parallel, _gst_for_dump);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initFEEngineBoundary() {
FEEngine & fem_boundary = getFEEngineBoundary();
fem_boundary.initShapeFunctions(_not_ghost);
fem_boundary.initShapeFunctions(_ghost);
fem_boundary.computeNormalsOnIntegrationPoints(_not_ghost);
fem_boundary.computeNormalsOnIntegrationPoints(_ghost);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initExplicit(AnalysisMethod analysis_method) {
AKANTU_DEBUG_IN();
//in case of switch from implicit to explicit
if(!this->isExplicit())
method = analysis_method;
if (integrator) delete integrator;
integrator = new CentralDifference();
UInt nb_nodes = acceleration->getSize();
UInt nb_degree_of_freedom = acceleration->getNbComponent();
std::stringstream sstr; sstr << id << ":increment_acceleration";
increment_acceleration = &(alloc<Real>(sstr.str(), nb_nodes, nb_degree_of_freedom, Real()));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initArraysPreviousDisplacment() {
AKANTU_DEBUG_IN();
this->setIncrementFlagOn();
if(not this->previous_displacement) {
UInt nb_nodes = this->mesh.getNbNodes();
std::stringstream sstr_disp_t;
sstr_disp_t << this->id << ":previous_displacement";
this->previous_displacement = &(this->alloc<Real > (sstr_disp_t.str(), nb_nodes, this->spatial_dimension, 0.));
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Allocate all the needed vectors. By default their are not necessarily set to
* 0
*
*/
void SolidMechanicsModel::initArrays() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
std::stringstream sstr_disp; sstr_disp << id << ":displacement";
// std::stringstream sstr_mass; sstr_mass << id << ":mass";
std::stringstream sstr_velo; sstr_velo << id << ":velocity";
std::stringstream sstr_acce; sstr_acce << id << ":acceleration";
std::stringstream sstr_forc; sstr_forc << id << ":force";
std::stringstream sstr_resi; sstr_resi << id << ":residual";
std::stringstream sstr_boun; sstr_boun << id << ":blocked_dofs";
displacement = &(alloc<Real>(sstr_disp.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
// mass = &(alloc<Real>(sstr_mass.str(), nb_nodes, spatial_dimension, 0));
velocity = &(alloc<Real>(sstr_velo.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
acceleration = &(alloc<Real>(sstr_acce.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
force = &(alloc<Real>(sstr_forc.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
residual = &(alloc<Real>(sstr_resi.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
blocked_dofs = &(alloc<bool>(sstr_boun.str(), nb_nodes, spatial_dimension, false));
std::stringstream sstr_curp; sstr_curp << id << ":current_position";
current_position = &(alloc<Real>(sstr_curp.str(), 0, spatial_dimension, REAL_INIT_VALUE));
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt, _ek_not_defined);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it, gt);
material_index.alloc(nb_element, 1, *it, gt);
material_local_numbering.alloc(nb_element, 1, *it, gt);
}
}
dof_synchronizer = new DOFSynchronizer(mesh, spatial_dimension);
dof_synchronizer->initLocalDOFEquationNumbers();
dof_synchronizer->initGlobalDOFEquationNumbers();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Initialize the model,basically it pre-compute the shapes, shapes derivatives
* and jacobian
*
*/
void SolidMechanicsModel::initModel() {
/// \todo add the current position as a parameter to initShapeFunctions for
/// large deformation
getFEEngine().initShapeFunctions(_not_ghost);
getFEEngine().initShapeFunctions(_ghost);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initPBC() {
Model::initPBC();
registerPBCSynchronizer();
// as long as there are ones on the diagonal of the matrix, we can put boudandary true for slaves
std::map<UInt, UInt>::iterator it = pbc_pair.begin();
std::map<UInt, UInt>::iterator end = pbc_pair.end();
UInt dim = mesh.getSpatialDimension();
while(it != end) {
for (UInt i=0; i<dim; ++i)
(*blocked_dofs)((*it).first,i) = true;
++it;
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::registerPBCSynchronizer(){
pbc_synch = new PBCSynchronizer(pbc_pair);
synch_registry->registerSynchronizer(*pbc_synch, _gst_smm_uv);
synch_registry->registerSynchronizer(*pbc_synch, _gst_smm_mass);
synch_registry->registerSynchronizer(*pbc_synch, _gst_smm_res);
synch_registry->registerSynchronizer(*pbc_synch, _gst_for_dump);
changeLocalEquationNumberForPBC(pbc_pair, mesh.getSpatialDimension());
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateCurrentPosition() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
current_position->resize(nb_nodes);
Real * current_position_val = current_position->storage();
Real * position_val = mesh.getNodes().storage();
Real * displacement_val = displacement->storage();
/// compute current_position = initial_position + displacement
memcpy(current_position_val, position_val, nb_nodes*spatial_dimension*sizeof(Real));
for (UInt n = 0; n < nb_nodes*spatial_dimension; ++n) {
*current_position_val++ += *displacement_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initializeUpdateResidualData() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
residual->resize(nb_nodes);
/// copy the forces in residual for boundary conditions
memcpy(residual->storage(), force->storage(), nb_nodes*spatial_dimension*sizeof(Real));
// start synchronization
synch_registry->asynchronousSynchronize(_gst_smm_uv);
synch_registry->waitEndSynchronize(_gst_smm_uv);
updateCurrentPosition();
AKANTU_DEBUG_OUT();
}
/*----------------------------------------------------------------------------*/
void SolidMechanicsModel::reInitialize()
{
}
/* -------------------------------------------------------------------------- */
/* Explicit scheme */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* This function compute the second member of the motion equation. That is to
* say the sum of forces @f$ r = F_{ext} - F_{int} @f$. @f$ F_{ext} @f$ is given
* by the user in the force vector, and @f$ F_{int} @f$ is computed as @f$
* F_{int} = \int_{\Omega} N \sigma d\Omega@f$
*
*/
void SolidMechanicsModel::updateResidual(bool need_initialize) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Assemble the internal forces");
// f = f_ext - f_int
// f = f_ext
if(need_initialize) initializeUpdateResidualData();
AKANTU_DEBUG_INFO("Compute local stresses");
std::vector<Material *>::iterator mat_it;
for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
mat.computeAllStresses(_not_ghost);
}
#ifdef AKANTU_DAMAGE_NON_LOCAL
/* ------------------------------------------------------------------------ */
/* Computation of the non local part */
this->non_local_manager->computeAllNonLocalStresses();
#endif
/* ------------------------------------------------------------------------ */
/* assembling the forces internal */
// communicate the stress
AKANTU_DEBUG_INFO("Send data for residual assembly");
synch_registry->asynchronousSynchronize(_gst_smm_stress);
AKANTU_DEBUG_INFO("Assemble residual for local elements");
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
mat.assembleResidual(_not_ghost);
}
AKANTU_DEBUG_INFO("Wait distant stresses");
// finalize communications
synch_registry->waitEndSynchronize(_gst_smm_stress);
AKANTU_DEBUG_INFO("Assemble residual for ghost elements");
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
mat.assembleResidual(_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::computeStresses() {
if (isExplicit()) {
// start synchronization
synch_registry->asynchronousSynchronize(_gst_smm_uv);
synch_registry->waitEndSynchronize(_gst_smm_uv);
// compute stresses on all local elements for each materials
std::vector<Material *>::iterator mat_it;
for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
mat.computeAllStresses(_not_ghost);
}
/* ------------------------------------------------------------------------ */
#ifdef AKANTU_DAMAGE_NON_LOCAL
/* Computation of the non local part */
this->non_local_manager->computeAllNonLocalStresses();
#endif
} else {
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
mat.computeAllStressesFromTangentModuli(_not_ghost);
}
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateResidualInternal() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Update the residual");
// f = f_ext - f_int - Ma - Cv = r - Ma - Cv;
if(method != _static) {
// f -= Ma
if(mass_matrix) {
// if full mass_matrix
Array<Real> * Ma = new Array<Real>(*acceleration, true, "Ma");
*Ma *= *mass_matrix;
/// \todo check unit conversion for implicit dynamics
// *Ma /= f_m2a
*residual -= *Ma;
delete Ma;
} else if (mass) {
// else lumped mass
UInt nb_nodes = acceleration->getSize();
UInt nb_degree_of_freedom = acceleration->getNbComponent();
Real * mass_val = mass->storage();
Real * accel_val = acceleration->storage();
Real * res_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*res_val -= *accel_val * *mass_val /f_m2a;
}
blocked_dofs_val++;
res_val++;
mass_val++;
accel_val++;
}
} else {
AKANTU_DEBUG_ERROR("No function called to assemble the mass matrix.");
}
// f -= Cv
if(velocity_damping_matrix) {
Array<Real> * Cv = new Array<Real>(*velocity);
*Cv *= *velocity_damping_matrix;
*residual -= *Cv;
delete Cv;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateAcceleration() {
AKANTU_DEBUG_IN();
updateResidualInternal();
if(method == _explicit_lumped_mass) {
/* residual = residual_{n+1} - M * acceleration_n therefore
solution = increment acceleration not acceleration */
solveLumped(*increment_acceleration,
*mass,
*residual,
*blocked_dofs,
f_m2a);
} else if (method == _explicit_consistent_mass) {
solve<NewmarkBeta::_acceleration_corrector>(*increment_acceleration);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::solveLumped(Array<Real> & x,
const Array<Real> & A,
const Array<Real> & b,
const Array<bool> & blocked_dofs,
Real alpha) {
Real * A_val = A.storage();
Real * b_val = b.storage();
Real * x_val = x.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
UInt nb_degrees_of_freedom = x.getSize() * x.getNbComponent();
for (UInt n = 0; n < nb_degrees_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*x_val = alpha * (*b_val / *A_val);
}
x_val++;
A_val++;
b_val++;
blocked_dofs_val++;
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::explicitPred() {
AKANTU_DEBUG_IN();
if(increment_flag) {
if(previous_displacement) increment->copy(*previous_displacement);
else increment->copy(*displacement);
}
AKANTU_DEBUG_ASSERT(integrator,"itegrator should have been allocated: "
<< "have called initExplicit ? "
<< "or initImplicit ?");
integrator->integrationSchemePred(time_step,
*displacement,
*velocity,
*acceleration,
*blocked_dofs);
if(increment_flag) {
Real * inc_val = increment->storage();
Real * dis_val = displacement->storage();
UInt nb_degree_of_freedom = displacement->getSize() * displacement->getNbComponent();
for (UInt n = 0; n < nb_degree_of_freedom; ++n) {
*inc_val = *dis_val - *inc_val;
inc_val++;
dis_val++;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::explicitCorr() {
AKANTU_DEBUG_IN();
integrator->integrationSchemeCorrAccel(time_step,
*displacement,
*velocity,
*acceleration,
*blocked_dofs,
*increment_acceleration);
if(previous_displacement) previous_displacement->copy(*displacement);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::solveStep() {
AKANTU_DEBUG_IN();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
this->explicitPred();
this->updateResidual();
this->updateAcceleration();
this->explicitCorr();
EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* Implicit scheme */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* Initialize the solver and create the sparse matrices needed.
*
*/
void SolidMechanicsModel::initSolver(__attribute__((unused)) SolverOptions & options) {
#if !defined(AKANTU_USE_MUMPS) && !defined(AKANTU_USE_PETSC)// or other solver in the future \todo add AKANTU_HAS_SOLVER in CMake
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#else
UInt nb_global_nodes = mesh.getNbGlobalNodes();
delete jacobian_matrix;
std::stringstream sstr; sstr << id << ":jacobian_matrix";
#ifdef AKANTU_USE_PETSC
jacobian_matrix = new PETScMatrix(nb_global_nodes * spatial_dimension, _symmetric, sstr.str(), memory_id);
#else
jacobian_matrix = new SparseMatrix(nb_global_nodes * spatial_dimension, _unsymmetric, sstr.str(), memory_id);
#endif //AKANTU_USE PETSC
jacobian_matrix->buildProfile(mesh, *dof_synchronizer, spatial_dimension);
if (!isExplicit()) {
delete stiffness_matrix;
std::stringstream sstr_sti; sstr_sti << id << ":stiffness_matrix";
#ifdef AKANTU_USE_PETSC
stiffness_matrix = new SparseMatrix(nb_global_nodes * spatial_dimension, _symmetric, sstr.str(), memory_id);
stiffness_matrix->buildProfile(mesh, *dof_synchronizer, spatial_dimension);
#else
stiffness_matrix = new SparseMatrix(*jacobian_matrix, sstr_sti.str(), memory_id);
#endif //AKANTU_USE_PETSC
}
delete solver;
std::stringstream sstr_solv; sstr_solv << id << ":solver";
#ifdef AKANTU_USE_PETSC
solver = new SolverPETSc(*jacobian_matrix, sstr_solv.str());
#elif defined(AKANTU_USE_MUMPS)
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
dof_synchronizer->initScatterGatherCommunicationScheme();
#else
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#endif //AKANTU_USE_MUMPS
if(solver)
solver->initialize(options);
#endif //AKANTU_HAS_SOLVER
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initJacobianMatrix() {
#if defined(AKANTU_USE_MUMPS) && !defined(AKANTU_USE_PETSC)
// @todo make it more flexible: this is an ugly patch to treat the case of non
// fix profile of the K matrix
delete jacobian_matrix;
std::stringstream sstr_sti; sstr_sti << id << ":jacobian_matrix";
jacobian_matrix = new SparseMatrix(*stiffness_matrix, sstr_sti.str(), memory_id);
std::stringstream sstr_solv; sstr_solv << id << ":solver";
delete solver;
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
if(solver)
solver->initialize(_solver_no_options);
#else
AKANTU_DEBUG_ERROR("You need to activate the solver mumps.");
#endif
}
/* -------------------------------------------------------------------------- */
/**
* Initialize the implicit solver, either for dynamic or static cases,
*
* @param dynamic
*/
void SolidMechanicsModel::initImplicit(bool dynamic, SolverOptions & solver_options) {
AKANTU_DEBUG_IN();
method = dynamic ? _implicit_dynamic : _static;
if (!increment) setIncrementFlagOn();
initSolver(solver_options);
if(method == _implicit_dynamic) {
if(integrator) delete integrator;
integrator = new TrapezoidalRule2();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initialAcceleration() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Solving Ma = f");
Solver * acc_solver = NULL;
std::stringstream sstr; sstr << id << ":tmp_mass_matrix";
SparseMatrix * tmp_mass = new SparseMatrix(*mass_matrix, sstr.str(), memory_id);
#ifdef AKANTU_USE_MUMPS
std::stringstream sstr_solver; sstr << id << ":solver_mass_matrix";
acc_solver = new SolverMumps(*mass_matrix, sstr_solver.str());
dof_synchronizer->initScatterGatherCommunicationScheme();
#else
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#endif //AKANTU_USE_MUMPS
acc_solver->initialize();
tmp_mass->applyBoundary(*blocked_dofs);
acc_solver->setRHS(*residual);
acc_solver->solve(*acceleration);
delete acc_solver;
delete tmp_mass;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleStiffnessMatrix() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Assemble the new stiffness matrix.");
stiffness_matrix->clear();
// call compute stiffness matrix on each local elements
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
(*mat_it)->assembleStiffnessMatrix(_not_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseMatrix & SolidMechanicsModel::initVelocityDampingMatrix() {
if(!velocity_damping_matrix)
velocity_damping_matrix =
new SparseMatrix(*jacobian_matrix, id + ":velocity_damping_matrix", memory_id);
return *velocity_damping_matrix;
}
/* -------------------------------------------------------------------------- */
template<>
bool SolidMechanicsModel::testConvergence<_scc_increment>(Real tolerance, Real & error){
AKANTU_DEBUG_IN();
UInt nb_nodes = displacement->getSize();
UInt nb_degree_of_freedom = displacement->getNbComponent();
error = 0;
Real norm[2] = {0., 0.};
Real * increment_val = increment->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
Real * displacement_val = displacement->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val) && is_local_node) {
norm[0] += *increment_val * *increment_val;
norm[1] += *displacement_val * *displacement_val;
}
blocked_dofs_val++;
increment_val++;
displacement_val++;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(norm, 2, _so_sum);
norm[0] = sqrt(norm[0]);
norm[1] = sqrt(norm[1]);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm[0]), "Something goes wrong in the solve phase");
if (norm[1] < Math::getTolerance()) {
error = norm[0];
AKANTU_DEBUG_OUT();
// cout<<"Error 1: "<<error<<endl;
return error < tolerance;
}
AKANTU_DEBUG_OUT();
if(norm[1] > Math::getTolerance())
error = norm[0] / norm[1];
else
error = norm[0]; //In case the total displacement is zero!
// cout<<"Error 2: "<<error<<endl;
return (error < tolerance);
}
/* -------------------------------------------------------------------------- */
template<>
bool SolidMechanicsModel::testConvergence<_scc_residual>(Real tolerance, Real & norm) {
AKANTU_DEBUG_IN();
UInt nb_nodes = residual->getSize();
UInt nb_degree_of_freedom = displacement->getNbComponent();
norm = 0;
Real * residual_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
if(is_local_node) {
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val)) {
norm += *residual_val * *residual_val;
}
blocked_dofs_val++;
residual_val++;
}
} else {
blocked_dofs_val += spatial_dimension;
residual_val += spatial_dimension;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum);
norm = sqrt(norm);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
AKANTU_DEBUG_OUT();
return (norm < tolerance);
}
/* -------------------------------------------------------------------------- */
template<>
bool SolidMechanicsModel::testConvergence<_scc_residual_mass_wgh>(Real tolerance,
Real & norm) {
AKANTU_DEBUG_IN();
UInt nb_nodes = residual->getSize();
norm = 0;
Real * residual_val = residual->storage();
Real * mass_val = this->mass->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
if(is_local_node) {
for (UInt d = 0; d < spatial_dimension; ++d) {
if(!(*blocked_dofs_val)) {
norm += *residual_val * *residual_val/(*mass_val * *mass_val);
}
blocked_dofs_val++;
residual_val++;
mass_val++;
}
} else {
blocked_dofs_val += spatial_dimension;
residual_val += spatial_dimension;
mass_val += spatial_dimension;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum);
norm = sqrt(norm);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
AKANTU_DEBUG_OUT();
return (norm < tolerance);
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::testConvergenceResidual(Real tolerance){
AKANTU_DEBUG_IN();
Real error=0;
bool res = this->testConvergence<_scc_residual>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::testConvergenceResidual(Real tolerance, Real & error){
AKANTU_DEBUG_IN();
bool res = this->testConvergence<_scc_residual>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::testConvergenceIncrement(Real tolerance){
AKANTU_DEBUG_IN();
Real error=0;
bool res = this->testConvergence<_scc_increment>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::testConvergenceIncrement(Real tolerance, Real & error){
AKANTU_DEBUG_IN();
bool res = this->testConvergence<_scc_increment>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::implicitPred() {
AKANTU_DEBUG_IN();
if(method == _implicit_dynamic)
integrator->integrationSchemePred(time_step,
*displacement,
*velocity,
*acceleration,
*blocked_dofs);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::implicitCorr() {
AKANTU_DEBUG_IN();
if(method == _implicit_dynamic) {
integrator->integrationSchemeCorrDispl(time_step,
*displacement,
*velocity,
*acceleration,
*blocked_dofs,
*increment);
} else {
UInt nb_nodes = displacement->getSize();
UInt nb_degree_of_freedom = displacement->getNbComponent() * nb_nodes;
Real * incr_val = increment->storage();
Real * disp_val = displacement->storage();
bool * boun_val = blocked_dofs->storage();
for (UInt j = 0; j < nb_degree_of_freedom; ++j, ++disp_val, ++incr_val, ++boun_val){
*incr_val *= (1. - *boun_val);
*disp_val += *incr_val;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateIncrement() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(previous_displacement,"The previous displacement has to be initialized."
<< " Are you working with Finite or Ineslactic deformations?");
UInt nb_nodes = displacement->getSize();
UInt nb_degree_of_freedom = displacement->getNbComponent() * nb_nodes;
Real * incr_val = increment->storage();
Real * disp_val = displacement->storage();
Real * prev_disp_val = previous_displacement->storage();
for (UInt j = 0; j < nb_degree_of_freedom; ++j, ++disp_val, ++incr_val, ++prev_disp_val)
*incr_val = (*disp_val - *prev_disp_val);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updatePreviousDisplacement() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(previous_displacement,"The previous displacement has to be initialized."
<< " Are you working with Finite or Ineslactic deformations?");
previous_displacement->copy(*displacement);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* Information */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::synchronizeBoundaries() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(synch_registry,"Synchronizer registry was not initialized."
<< " Did you call initParallel?");
synch_registry->synchronize(_gst_smm_boundary);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::synchronizeResidual() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(synch_registry,"Synchronizer registry was not initialized."
<< " Did you call initPBC?");
synch_registry->synchronize(_gst_smm_res);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::setIncrementFlagOn() {
AKANTU_DEBUG_IN();
if(!increment) {
UInt nb_nodes = mesh.getNbNodes();
std::stringstream sstr_inc; sstr_inc << id << ":increment";
increment = &(alloc<Real>(sstr_inc.str(), nb_nodes, spatial_dimension, 0.));
}
increment_flag = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getStableTimeStep() {
AKANTU_DEBUG_IN();
Real min_dt = getStableTimeStep(_not_ghost);
/// reduction min over all processors
StaticCommunicator::getStaticCommunicator().allReduce(&min_dt, 1, _so_min);
AKANTU_DEBUG_OUT();
return min_dt;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getStableTimeStep(const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
Material ** mat_val = &(materials.at(0));
Real min_dt = std::numeric_limits<Real>::max();
updateCurrentPosition();
Element elem;
elem.ghost_type = ghost_type;
elem.kind = _ek_regular;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_regular);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type, _ek_regular);
for(; it != end; ++it) {
elem.type = *it;
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
UInt nb_element = mesh.getNbElement(*it);
Array<UInt>::const_scalar_iterator mat_indexes = material_index(*it, ghost_type).begin();
Array<UInt>::const_scalar_iterator mat_loc_num = material_local_numbering(*it, ghost_type).begin();
Array<Real> X(0, nb_nodes_per_element*spatial_dimension);
FEEngine::extractNodalToElementField(mesh, *current_position,
X, *it, _not_ghost);
Array<Real>::matrix_iterator X_el =
X.begin(spatial_dimension, nb_nodes_per_element);
for (UInt el = 0; el < nb_element; ++el, ++X_el, ++mat_indexes, ++mat_loc_num) {
elem.element = *mat_loc_num;
Real el_h = getFEEngine().getElementInradius(*X_el, *it);
Real el_c = mat_val[*mat_indexes]->getCelerity(elem);
Real el_dt = el_h / el_c;
min_dt = std::min(min_dt, el_dt);
}
}
AKANTU_DEBUG_OUT();
return min_dt;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getKineticEnergy() {
AKANTU_DEBUG_IN();
if (!mass && !mass_matrix)
AKANTU_DEBUG_ERROR("No function called to assemble the mass matrix.");
Real ekin = 0.;
UInt nb_nodes = mesh.getNbNodes();
Real * vel_val = velocity->storage();
Real * mass_val = mass->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
Real mv2 = 0;
bool is_local_node = mesh.isLocalOrMasterNode(n);
bool is_not_pbc_slave_node = !isPBCSlaveNode(n);
bool count_node = is_local_node && is_not_pbc_slave_node;
for (UInt i = 0; i < spatial_dimension; ++i) {
if (count_node)
mv2 += *vel_val * *vel_val * *mass_val;
vel_val++;
mass_val++;
}
ekin += mv2;
}
StaticCommunicator::getStaticCommunicator().allReduce(&ekin, 1, _so_sum);
AKANTU_DEBUG_OUT();
return ekin * .5;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getKineticEnergy(const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
Array<Real> vel_on_quad(nb_quadrature_points, spatial_dimension);
Array<UInt> filter_element(1, 1, index);
getFEEngine().interpolateOnIntegrationPoints(*velocity, vel_on_quad,
spatial_dimension,
type, _not_ghost,
filter_element);
Array<Real>::vector_iterator vit = vel_on_quad.begin(spatial_dimension);
Array<Real>::vector_iterator vend = vel_on_quad.end(spatial_dimension);
Vector<Real> rho_v2(nb_quadrature_points);
Real rho = materials[material_index(type)(index)]->getRho();
for (UInt q = 0; vit != vend; ++vit, ++q) {
rho_v2(q) = rho * vit->dot(*vit);
}
AKANTU_DEBUG_OUT();
return .5*getFEEngine().integrate(rho_v2, type, index);
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getExternalWork() {
AKANTU_DEBUG_IN();
Real * incr_or_velo = NULL;
if(this->method == _static){
incr_or_velo = this->increment->storage();
}
else
incr_or_velo = this->velocity->storage();
Real * forc = this->force->storage();
Real * resi = this->residual->storage();
bool * boun = this->blocked_dofs->storage();
Real work = 0.;
UInt nb_nodes = this->mesh.getNbNodes();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = this->mesh.isLocalOrMasterNode(n);
bool is_not_pbc_slave_node = !this->isPBCSlaveNode(n);
bool count_node = is_local_node && is_not_pbc_slave_node;
for (UInt i = 0; i < this->spatial_dimension; ++i) {
if (count_node) {
if(*boun)
work -= *resi * *incr_or_velo;
else
work += *forc * *incr_or_velo;
}
++incr_or_velo;
++forc;
++resi;
++boun;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&work, 1, _so_sum);
if(this->method != _static)
work *= this->time_step;
AKANTU_DEBUG_OUT();
return work;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getEnergy(const std::string & energy_id) {
AKANTU_DEBUG_IN();
if (energy_id == "kinetic") {
return getKineticEnergy();
} else if (energy_id == "external work"){
return getExternalWork();
}
Real energy = 0.;
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
energy += (*mat_it)->getEnergy(energy_id);
}
/// reduction sum over all processors
StaticCommunicator::getStaticCommunicator().allReduce(&energy, 1, _so_sum);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getEnergy(const std::string & energy_id,
const ElementType & type,
UInt index) {
AKANTU_DEBUG_IN();
if (energy_id == "kinetic") {
return getKineticEnergy(type, index);
}
std::vector<Material *>::iterator mat_it;
UInt mat_index = this->material_index(type, _not_ghost)(index);
UInt mat_loc_num = this->material_local_numbering(type, _not_ghost)(index);
Real energy = this->materials[mat_index]->getEnergy(energy_id, type, mat_loc_num);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event) {
AKANTU_DEBUG_IN();
this->getFEEngine().initShapeFunctions(_not_ghost);
this->getFEEngine().initShapeFunctions(_ghost);
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
Mesh::type_iterator it = this->mesh.firstType(spatial_dimension, gt, _ek_not_defined);
Mesh::type_iterator end = this->mesh.lastType(spatial_dimension, gt, _ek_not_defined);
for(; it != end; ++it) {
UInt nb_element = this->mesh.getNbElement(*it, gt);
if(!material_index.exists(*it, gt)) {
this->material_index .alloc(nb_element, 1, *it, gt);
this->material_local_numbering.alloc(nb_element, 1, *it, gt);
} else {
this->material_index (*it, gt).resize(nb_element);
this->material_local_numbering(*it, gt).resize(nb_element);
}
}
}
Array<Element>::const_iterator<Element> it = element_list.begin();
Array<Element>::const_iterator<Element> end = element_list.end();
ElementTypeMapArray<UInt> filter("new_element_filter", this->getID());
for (UInt el = 0; it != end; ++it, ++el) {
const Element & elem = *it;
if(!filter.exists(elem.type, elem.ghost_type))
filter.alloc(0, 1, elem.type, elem.ghost_type);
filter(elem.type, elem.ghost_type).push_back(elem.element);
}
this->assignMaterialToElements(&filter);
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
(*mat_it)->onElementsAdded(element_list, event);
}
if(method == _explicit_lumped_mass) this->assembleMassLumped();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onElementsRemoved(__attribute__((unused)) const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event) {
this->getFEEngine().initShapeFunctions(_not_ghost);
this->getFEEngine().initShapeFunctions(_ghost);
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
(*mat_it)->onElementsRemoved(element_list, new_numbering, event);
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onNodesAdded(const Array<UInt> & nodes_list,
__attribute__((unused)) const NewNodesEvent & event) {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
if(displacement) displacement->resize(nb_nodes);
if(mass ) mass ->resize(nb_nodes);
if(velocity ) velocity ->resize(nb_nodes);
if(acceleration) acceleration->resize(nb_nodes);
if(force ) force ->resize(nb_nodes);
if(residual ) residual ->resize(nb_nodes);
if(blocked_dofs) blocked_dofs->resize(nb_nodes);
if(previous_displacement) previous_displacement->resize(nb_nodes);
if(increment_acceleration) increment_acceleration->resize(nb_nodes);
if(increment) increment->resize(nb_nodes);
if(current_position) current_position->resize(nb_nodes);
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
(*mat_it)->onNodesAdded(nodes_list, event);
}
delete dof_synchronizer;
dof_synchronizer = new DOFSynchronizer(mesh, spatial_dimension);
dof_synchronizer->initLocalDOFEquationNumbers();
dof_synchronizer->initGlobalDOFEquationNumbers();
if (method != _explicit_lumped_mass) {
this->initSolver();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onNodesRemoved(__attribute__((unused)) const Array<UInt> & element_list,
const Array<UInt> & new_numbering,
__attribute__((unused)) const RemovedNodesEvent & event) {
if(displacement) mesh.removeNodesFromArray(*displacement, new_numbering);
if(mass ) mesh.removeNodesFromArray(*mass , new_numbering);
if(velocity ) mesh.removeNodesFromArray(*velocity , new_numbering);
if(acceleration) mesh.removeNodesFromArray(*acceleration, new_numbering);
if(force ) mesh.removeNodesFromArray(*force , new_numbering);
if(residual ) mesh.removeNodesFromArray(*residual , new_numbering);
if(blocked_dofs) mesh.removeNodesFromArray(*blocked_dofs, new_numbering);
if(increment_acceleration) mesh.removeNodesFromArray(*increment_acceleration, new_numbering);
if(increment) mesh.removeNodesFromArray(*increment , new_numbering);
delete dof_synchronizer;
dof_synchronizer = new DOFSynchronizer(mesh, spatial_dimension);
dof_synchronizer->initLocalDOFEquationNumbers();
dof_synchronizer->initGlobalDOFEquationNumbers();
if (method != _explicit_lumped_mass) {
this->initSolver();
}
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::isInternal(const std::string & field_name,
const ElementKind & element_kind) {
bool is_internal = false;
/// check if at least one material contains field_id as an internal
for (UInt m = 0; m < materials.size() && !is_internal; ++m) {
is_internal |= materials[m]->isInternal<Real>(field_name, element_kind);
}
return is_internal;
}
/* -------------------------------------------------------------------------- */
ElementTypeMap<UInt>
SolidMechanicsModel::getInternalDataPerElem(const std::string & field_name,
const ElementKind & element_kind) {
if (!(this->isInternal(field_name, element_kind)))
AKANTU_EXCEPTION("unknown internal " << field_name);
for (UInt m = 0; m < materials.size(); ++m) {
if (materials[m]->isInternal<Real>(field_name, element_kind))
return materials[m]->getInternalDataPerElem<Real>(field_name, element_kind);
}
return ElementTypeMap<UInt>();
}
/* -------------------------------------------------------------------------- */
ElementTypeMapArray<Real> &
SolidMechanicsModel::flattenInternal(const std::string & field_name,
const ElementKind & kind,
const GhostType ghost_type) {
std::pair<std::string, ElementKind> key(field_name, kind);
if (this->registered_internals.count(key) == 0) {
this->registered_internals[key] =
new ElementTypeMapArray<Real>(field_name, this->id);
}
ElementTypeMapArray<Real> * internal_flat = this->registered_internals[key];
typedef ElementTypeMapArray<Real>::type_iterator iterator;
iterator tit = internal_flat->firstType(spatial_dimension, ghost_type, kind);
iterator end = internal_flat->lastType(spatial_dimension, ghost_type, kind);
for (; tit != end; ++tit) {
ElementType type = *tit;
(*internal_flat)(type, ghost_type).clear();
}
for (UInt m = 0; m < materials.size(); ++m) {
if (materials[m]->isInternal<Real>(field_name, kind))
materials[m]->flattenInternal(field_name, *internal_flat, ghost_type,
kind);
}
return *internal_flat;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::flattenAllRegisteredInternals(
const ElementKind & kind) {
typedef std::map<std::pair<std::string, ElementKind>,
ElementTypeMapArray<Real> *>::iterator iterator;
iterator it = this->registered_internals.begin();
iterator end = this->registered_internals.end();
while (it != end) {
if (kind == it->first.second)
this->flattenInternal(it->first.first, kind);
++it;
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onDump(){
this->flattenAllRegisteredInternals(_ek_regular);
}
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
dumper::Field * SolidMechanicsModel
::createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const UInt & spatial_dimension,
const ElementKind & kind) {
dumper::Field * field = NULL;
if(field_name == "partitions")
field = mesh.createElementalField<UInt, dumper::ElementPartitionField>(mesh.getConnectivities(),group_name,spatial_dimension,kind);
else if(field_name == "material_index")
field = mesh.createElementalField<UInt, Vector, dumper::ElementalField >(material_index,group_name,spatial_dimension,kind);
else {
// this copy of field_name is used to compute derivated data such as
// strain and von mises stress that are based on grad_u and stress
std::string field_name_copy(field_name);
if (field_name == "strain"
|| field_name == "Green strain"
|| field_name == "principal strain"
|| field_name == "principal Green strain")
field_name_copy = "grad_u";
else if (field_name == "Von Mises stress")
field_name_copy = "stress";
bool is_internal = this->isInternal(field_name_copy,kind);
if (is_internal) {
ElementTypeMap<UInt> nb_data_per_elem = this->getInternalDataPerElem(field_name_copy, kind);
ElementTypeMapArray<Real> & internal_flat = this->flattenInternal(field_name_copy,kind);
field = mesh.createElementalField<Real, dumper::InternalMaterialField>(internal_flat,
group_name,
spatial_dimension,kind,nb_data_per_elem);
if (field_name == "strain"){
dumper::ComputeStrain<false> * foo = new dumper::ComputeStrain<false>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
} else if (field_name == "Von Mises stress") {
dumper::ComputeVonMisesStress * foo = new dumper::ComputeVonMisesStress(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
} else if (field_name == "Green strain") {
dumper::ComputeStrain<true> * foo = new dumper::ComputeStrain<true>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
} else if (field_name == "principal strain") {
dumper::ComputePrincipalStrain<false> * foo = new dumper::ComputePrincipalStrain<false>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
} else if (field_name == "principal Green strain") {
dumper::ComputePrincipalStrain<true> * foo = new dumper::ComputePrincipalStrain<true>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
}
//treat the paddings
if (padding_flag){
if (field_name == "stress"){
if (spatial_dimension == 2) {
dumper::StressPadder<2> * foo = new dumper::StressPadder<2>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
}
} else if (field_name == "strain" || field_name == "Green strain"){
if (spatial_dimension == 2) {
dumper::StrainPadder<2> * foo = new dumper::StrainPadder<2>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
}
}
}
// homogenize the field
dumper::ComputeFunctorInterface * foo =
dumper::HomogenizerProxy::createHomogenizer(*field);
field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
}
}
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
std::map<std::string,Array<Real>* > real_nodal_fields;
real_nodal_fields["displacement" ] = displacement;
real_nodal_fields["mass" ] = mass;
real_nodal_fields["velocity" ] = velocity;
real_nodal_fields["acceleration" ] = acceleration;
real_nodal_fields["force" ] = force;
real_nodal_fields["residual" ] = residual;
real_nodal_fields["increment" ] = increment;
dumper::Field * field = NULL;
if (padding_flag)
field = mesh.createNodalField(real_nodal_fields[field_name], group_name, 3);
else
field = mesh.createNodalField(real_nodal_fields[field_name], group_name);
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel::createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
std::map<std::string,Array<bool>* > uint_nodal_fields;
uint_nodal_fields["blocked_dofs" ] = blocked_dofs;
dumper::Field * field = NULL;
field = mesh.createNodalField(uint_nodal_fields[field_name],group_name);
return field;
}
/* -------------------------------------------------------------------------- */
#else
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel
::createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const UInt & spatial_dimension,
const ElementKind & kind){
return NULL;
}
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
return NULL;
}
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel::createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
return NULL;
}
#endif
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(const std::string & dumper_name) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
mesh.dump(dumper_name);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(const std::string & dumper_name, UInt step) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
mesh.dump(dumper_name, step);
}
/* ------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(const std::string & dumper_name, Real time, UInt step) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
mesh.dump(dumper_name, time, step);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump() {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
mesh.dump();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(UInt step) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
mesh.dump(step);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(Real time, UInt step) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
mesh.dump(time, step);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::computeCauchyStresses() {
AKANTU_DEBUG_IN();
// call compute stiffness matrix on each local elements
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
if(mat.isFiniteDeformation())
mat.computeAllCauchyStresses(_not_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::saveStressAndStrainBeforeDamage() {
EventManager::sendEvent(SolidMechanicsModelEvent::BeginningOfDamageIterationEvent());
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateEnergiesAfterDamage() {
EventManager::sendEvent(SolidMechanicsModelEvent::AfterDamageEvent());
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Solid Mechanics Model [" << std::endl;
stream << space << " + id : " << id << std::endl;
stream << space << " + spatial dimension : " << spatial_dimension << std::endl;
stream << space << " + fem [" << std::endl;
getFEEngine().printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << " + nodals information [" << std::endl;
displacement->printself(stream, indent + 2);
mass ->printself(stream, indent + 2);
velocity ->printself(stream, indent + 2);
acceleration->printself(stream, indent + 2);
force ->printself(stream, indent + 2);
residual ->printself(stream, indent + 2);
blocked_dofs->printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << " + material information [" << std::endl;
material_index.printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << " + materials [" << std::endl;
std::vector<Material *>::const_iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
const Material & mat = *(*mat_it);
mat.printself(stream, indent + 1);
}
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model.hh b/src/model/solid_mechanics/solid_mechanics_model.hh
index 8f1e4d81d..4595f33ae 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,774 +1,775 @@
/**
* @file solid_mechanics_model.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Jul 27 2010
- * @date last modification: Tue Sep 16 2014
+ * @date last modification: Fri Dec 18 2015
*
* @brief Model of Solid Mechanics
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_HH__
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_types.hh"
#include "model.hh"
#include "data_accessor.hh"
#include "mesh.hh"
#include "dumpable.hh"
#include "boundary_condition.hh"
#include "integrator_gauss.hh"
#include "shape_lagrange.hh"
#include "integration_scheme_2nd_order.hh"
#include "solver.hh"
#include "material_selector.hh"
#include "solid_mechanics_model_event_handler.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class Material;
class IntegrationScheme2ndOrder;
class SparseMatrix;
class DumperIOHelper;
class NonLocalManager;
}
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
struct SolidMechanicsModelOptions : public ModelOptions {
SolidMechanicsModelOptions(AnalysisMethod analysis_method = _explicit_lumped_mass,
bool no_init_materials = false) :
analysis_method(analysis_method),
no_init_materials(no_init_materials) { }
AnalysisMethod analysis_method;
bool no_init_materials;
};
extern const SolidMechanicsModelOptions default_solid_mechanics_model_options;
class SolidMechanicsModel : public Model,
public DataAccessor,
public MeshEventHandler,
public BoundaryCondition<SolidMechanicsModel>,
public EventHandlerManager<SolidMechanicsModelEventHandler> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
class NewMaterialElementsEvent : public NewElementsEvent {
public:
AKANTU_GET_MACRO_NOT_CONST(MaterialList, material, Array <UInt> &);
AKANTU_GET_MACRO(MaterialList, material, const Array <UInt> &);
protected:
Array <UInt> material;
};
typedef FEEngineTemplate <IntegratorGauss, ShapeLagrange> MyFEEngineType;
protected:
typedef EventHandlerManager <SolidMechanicsModelEventHandler> EventManager;
public:
SolidMechanicsModel(Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "solid_mechanics_model",
const MemoryID & memory_id = 0);
virtual ~SolidMechanicsModel();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize completely the model
virtual void initFull(const ModelOptions & options = default_solid_mechanics_model_options);
/// initialize the fem object needed for boundary conditions
void initFEEngineBoundary();
/// register the tags associated with the parallel synchronizer
virtual void initParallel(MeshPartition *partition,
DataAccessor *data_accessor = NULL);
/// allocate all vectors
virtual void initArrays();
/// allocate all vectors
void initArraysPreviousDisplacment();
/// initialize all internal arrays for materials
virtual void initMaterials();
/// initialize the model
virtual void initModel();
/// init PBC synchronizer
void initPBC();
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/// re-initialize model to set fields to 0
void reInitialize();
/* ------------------------------------------------------------------------ */
/* PBC */
/* ------------------------------------------------------------------------ */
public:
/// change the equation number for proper assembly when using PBC
// void changeEquationNumberforPBC(std::map <UInt, UInt> & pbc_pair);
/// synchronize Residual for output
void synchronizeResidual();
protected:
/// register PBC synchronizer
void registerPBCSynchronizer();
/* ------------------------------------------------------------------------ */
/* Explicit */
/* ------------------------------------------------------------------------ */
public:
/// initialize the stuff for the explicit scheme
void initExplicit(AnalysisMethod analysis_method = _explicit_lumped_mass);
bool isExplicit() {
return method == _explicit_lumped_mass || method == _explicit_consistent_mass;
}
/// initialize the array needed by updateResidual (residual, current_position)
void initializeUpdateResidualData();
/// update the current position vector
void updateCurrentPosition();
/// assemble the residual for the explicit scheme
virtual void updateResidual(bool need_initialize = true);
/**
* \brief compute the acceleration from the residual
* this function is the explicit equivalent to solveDynamic in implicit
* In the case of lumped mass just divide the residual by the mass
* In the case of not lumped mass call solveDynamic<_acceleration_corrector>
*/
void updateAcceleration();
///Update the increment of displacement
void updateIncrement();
///Copy the actuel displacement into previous displacement
void updatePreviousDisplacement();
///Save stress and strain through EventManager
void saveStressAndStrainBeforeDamage();
///Update energies through EventManager
void updateEnergiesAfterDamage();
/// Solve the system @f[ A x = \alpha b @f] with A a lumped matrix
void solveLumped(Array <Real> & x,
const Array <Real> & A,
const Array <Real> & b,
const Array <bool> & blocked_dofs,
Real alpha);
/// explicit integration predictor
void explicitPred();
/// explicit integration corrector
void explicitCorr();
public:
void solveStep();
/* ------------------------------------------------------------------------ */
/* Implicit */
/* ------------------------------------------------------------------------ */
public:
/// initialize the solver and the jacobian_matrix (called by initImplicit)
void initSolver(SolverOptions & options = _solver_no_options);
/// initialize the stuff for the implicit solver
void initImplicit(bool dynamic = false,
SolverOptions & solver_options = _solver_no_options);
/// solve Ma = f to get the initial acceleration
void initialAcceleration();
/// assemble the stiffness matrix
void assembleStiffnessMatrix();
public:
/**
* solve a step (predictor + convergence loop + corrector) using the
* the given convergence method (see akantu::SolveConvergenceMethod)
* and the given convergence criteria (see
* akantu::SolveConvergenceCriteria)
**/
template <SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance, UInt max_iteration = 100);
template <SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance,
Real & error,
UInt max_iteration = 100,
bool do_not_factorize = false);
public:
/**
* solve Ku = f using the the given convergence method (see
* akantu::SolveConvergenceMethod) and the given convergence
* criteria (see akantu::SolveConvergenceCriteria)
**/
template <SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool solveStatic(Real tolerance, UInt max_iteration,
bool do_not_factorize = false);
/// test if the system is converged
template <SolveConvergenceCriteria criteria>
bool testConvergence(Real tolerance, Real & error);
/// test the convergence (norm of increment)
bool testConvergenceIncrement(Real tolerance) __attribute__((deprecated));
bool testConvergenceIncrement(Real tolerance, Real & error) __attribute__((deprecated));
/// test the convergence (norm of residual)
bool testConvergenceResidual(Real tolerance) __attribute__((deprecated));
bool testConvergenceResidual(Real tolerance, Real & error) __attribute__((deprecated));
/// create and return the velocity damping matrix
SparseMatrix & initVelocityDampingMatrix();
/// implicit time integration predictor
void implicitPred();
/// implicit time integration corrector
void implicitCorr();
/// compute the Cauchy stress on user demand.
void computeCauchyStresses();
/// compute A and solve @f[ A\delta u = f_ext - f_int @f]
template <NewmarkBeta::IntegrationSchemeCorrectorType type>
void solve(Array<Real> &increment, Real block_val = 1.,
bool need_factorize = true, bool has_profile_changed = false);
protected:
/// finish the computation of residual to solve in increment
void updateResidualInternal();
/// compute the support reaction and store it in force
void updateSupportReaction();
private:
/// re-initialize the J matrix (to use if the profile of K changed)
void initJacobianMatrix();
/* ------------------------------------------------------------------------ */
/* Explicit/Implicit */
/* ------------------------------------------------------------------------ */
public:
/// Update the stresses for the computation of the residual of the Stiffness
/// matrix in the case of finite deformation
void computeStresses();
/// synchronize the ghost element boundaries values
void synchronizeBoundaries();
/* ------------------------------------------------------------------------ */
/* Materials (solid_mechanics_model_material.cc) */
/* ------------------------------------------------------------------------ */
public:
/// registers all the custom materials of a given type present in the input file
template <typename M>
void registerNewCustomMaterials(const ID & mat_type);
/// register an empty material of a given type
template <typename M>
Material & registerNewEmptyMaterial(const std::string & name);
// /// Use a UIntData in the mesh to specify the material to use per element
// void setMaterialIDsFromIntData(const std::string & data_name);
/// reassigns materials depending on the material selector
virtual void reassignMaterial();
/// apply a constant eigen_grad_u on all quadrature points of a given material
virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const ID & material_name, const GhostType ghost_type = _not_ghost);
protected:
/// register a material in the dynamic database
template <typename M>
Material & registerNewMaterial(const ParserSection & mat_section);
/// read the material files to instantiate all the materials
void instantiateMaterials();
/// set the element_id_by_material and add the elements to the good materials
void assignMaterialToElements(const ElementTypeMapArray<UInt> * filter = NULL);
/* ------------------------------------------------------------------------ */
/* Mass (solid_mechanics_model_mass.cc) */
/* ------------------------------------------------------------------------ */
public:
/// assemble the lumped mass matrix
void assembleMassLumped();
/// assemble the mass matrix for consistent mass resolutions
void assembleMass();
protected:
/// assemble the lumped mass matrix for local and ghost elements
void assembleMassLumped(GhostType ghost_type);
/// assemble the mass matrix for either _ghost or _not_ghost elements
void assembleMass(GhostType ghost_type);
/// fill a vector of rho
void computeRho(Array <Real> & rho,
ElementType type,
GhostType ghost_type);
/// compute the kinetic energy
Real getKineticEnergy();
Real getKineticEnergy(const ElementType & type, UInt index);
/// compute the external work (for impose displacement, the velocity should be given too)
Real getExternalWork();
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
inline virtual UInt getNbDataForElements(const Array <Element> & elements,
SynchronizationTag tag) const;
inline virtual void packElementData(CommunicationBuffer & buffer,
const Array <Element> & elements,
SynchronizationTag tag) const;
inline virtual void unpackElementData(CommunicationBuffer & buffer,
const Array <Element> & elements,
SynchronizationTag tag);
inline virtual UInt getNbDataToPack(SynchronizationTag tag) const;
inline virtual UInt getNbDataToUnpack(SynchronizationTag tag) const;
inline virtual void packData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag) const;
inline virtual void unpackData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag);
protected:
inline void splitElementByMaterial(const Array <Element> & elements,
Array <Element> * elements_per_mat) const;
/* ------------------------------------------------------------------------ */
/* Mesh Event Handler inherited members */
/* ------------------------------------------------------------------------ */
protected:
virtual void onNodesAdded(const Array <UInt> & nodes_list,
const NewNodesEvent & event);
virtual void onNodesRemoved(const Array <UInt> & element_list,
const Array <UInt> & new_numbering,
const RemovedNodesEvent & event);
virtual void onElementsAdded(const Array <Element> & nodes_list,
const NewElementsEvent & event);
virtual void onElementsRemoved(const Array <Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event);
virtual void onElementsChanged(__attribute__((unused)) const Array<Element> & old_elements_list,
__attribute__((unused)) const Array<Element> & new_elements_list,
__attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const ChangedElementsEvent & event) {};
/* ------------------------------------------------------------------------ */
/* Dumpable interface (kept for convenience) and dumper relative functions */
/* ------------------------------------------------------------------------ */
public:
virtual void onDump();
//! decide wether a field is a material internal or not
bool isInternal(const std::string & field_name, const ElementKind & element_kind);
#ifndef SWIG
//! give the amount of data per element
virtual ElementTypeMap<UInt> getInternalDataPerElem(const std::string & field_name,
const ElementKind & kind);
//! flatten a given material internal field
ElementTypeMapArray<Real> & flattenInternal(const std::string & field_name,
const ElementKind & kind,
const GhostType ghost_type = _not_ghost);
//! flatten all the registered material internals
void flattenAllRegisteredInternals(const ElementKind & kind);
#endif
virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field * createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const UInt & spatial_dimension,
const ElementKind & kind);
virtual void dump(const std::string & dumper_name);
virtual void dump(const std::string & dumper_name, UInt step);
virtual void dump(const std::string & dumper_name, Real time, UInt step);
virtual void dump();
virtual void dump(UInt step);
virtual void dump(Real time, UInt step);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// return the dimension of the system space
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// get the current value of the time step
AKANTU_GET_MACRO(TimeStep, time_step, Real);
/// set the value of the time step
void setTimeStep(Real time_step);
/// return the of iterations done in the last solveStep
AKANTU_GET_MACRO(NumberIter, n_iter, UInt);
/// get the value of the conversion from forces/ mass to acceleration
AKANTU_GET_MACRO(F_M2A, f_m2a, Real);
/// set the value of the conversion from forces/ mass to acceleration
AKANTU_SET_MACRO(F_M2A, f_m2a, Real);
/// get the SolidMechanicsModel::displacement vector
AKANTU_GET_MACRO(Displacement, *displacement, Array <Real> &);
/// get the SolidMechanicsModel::previous_displacement vector
AKANTU_GET_MACRO(PreviousDisplacement, *previous_displacement, Array <Real> &);
/// get the SolidMechanicsModel::current_position vector \warn only consistent
/// after a call to SolidMechanicsModel::updateCurrentPosition
AKANTU_GET_MACRO(CurrentPosition, *current_position, const Array <Real> &);
/// get the SolidMechanicsModel::increment vector \warn only consistent if
/// SolidMechanicsModel::setIncrementFlagOn has been called before
AKANTU_GET_MACRO(Increment, *increment, Array <Real> &);
/// get the lumped SolidMechanicsModel::mass vector
AKANTU_GET_MACRO(Mass, *mass, Array <Real> &);
/// get the SolidMechanicsModel::velocity vector
AKANTU_GET_MACRO(Velocity, *velocity, Array <Real> &);
/// get the SolidMechanicsModel::acceleration vector, updated by
/// SolidMechanicsModel::updateAcceleration
AKANTU_GET_MACRO(Acceleration, *acceleration, Array <Real> &);
/// get the SolidMechanicsModel::force vector (boundary forces)
AKANTU_GET_MACRO(Force, *force, Array <Real> &);
/// get the SolidMechanicsModel::residual vector, computed by
/// SolidMechanicsModel::updateResidual
AKANTU_GET_MACRO(Residual, *residual, Array <Real> &);
/// get the SolidMechanicsModel::blocked_dofs vector
AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array <bool> &);
/// get the SolidMechnicsModel::incrementAcceleration vector
AKANTU_GET_MACRO(IncrementAcceleration, *increment_acceleration, Array <Real> &);
/// get the value of the SolidMechanicsModel::increment_flag
AKANTU_GET_MACRO(IncrementFlag, increment_flag, bool);
/// get a particular material (by material index)
inline Material & getMaterial(UInt mat_index);
/// get a particular material (by material index)
inline const Material & getMaterial(UInt mat_index) const;
/// get a particular material (by material name)
inline Material & getMaterial(const std::string & name);
/// get a particular material (by material name)
inline const Material & getMaterial(const std::string & name) const;
/// get a particular material id from is name
inline UInt getMaterialIndex(const std::string & name) const;
/// give the number of materials
inline UInt getNbMaterials() const {
return materials.size();
}
inline void setMaterialSelector(MaterialSelector & selector);
/// give the material internal index from its id
Int getInternalIndexFromID(const ID & id) const;
/// compute the stable time step
Real getStableTimeStep();
/// get the energies
Real getEnergy(const std::string & energy_id);
/// compute the energy for energy
Real getEnergy(const std::string & energy_id, const ElementType & type, UInt index);
/**
* @brief set the SolidMechanicsModel::increment_flag to on, the activate the
* update of the SolidMechanicsModel::increment vector
*/
void setIncrementFlagOn();
/// get the stiffness matrix
AKANTU_GET_MACRO(StiffnessMatrix, *stiffness_matrix, SparseMatrix &);
/// get the global jacobian matrix of the system
AKANTU_GET_MACRO(GlobalJacobianMatrix, *jacobian_matrix, const SparseMatrix &);
/// get the mass matrix
AKANTU_GET_MACRO(MassMatrix, *mass_matrix, SparseMatrix &);
/// get the velocity damping matrix
AKANTU_GET_MACRO(VelocityDampingMatrix, *velocity_damping_matrix, SparseMatrix &);
/// get the FEEngine object to integrate or interpolate on the boundary
inline FEEngine & getFEEngineBoundary(const ID & name = "");
/// get integrator
AKANTU_GET_MACRO(Integrator, *integrator, const IntegrationScheme2ndOrder &);
/// get access to the internal solver
AKANTU_GET_MACRO(Solver, *solver, Solver &);
/// get synchronizer
AKANTU_GET_MACRO(Synchronizer, *synch_parallel, const DistributedSynchronizer &);
AKANTU_GET_MACRO(MaterialByElement, material_index, const ElementTypeMapArray<UInt> &);
/// vectors containing local material element index for each global element index
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialByElement, material_index, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialByElement, material_index, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialLocalNumbering, material_local_numbering, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialLocalNumbering, material_local_numbering, UInt);
/// Get the type of analysis method used
AKANTU_GET_MACRO(AnalysisMethod, method, AnalysisMethod);
/// get the non-local manager
AKANTU_GET_MACRO(NonLocalManager, *non_local_manager, NonLocalManager &);
template <int dim, class model_type>
friend struct ContactData;
template <int Dim, AnalysisMethod s, ContactResolutionMethod r>
friend class ContactResolution;
protected:
friend class Material;
protected:
/// compute the stable time step
Real getStableTimeStep(const GhostType & ghost_type);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// number of iterations
UInt n_iter;
/// time step
Real time_step;
/// conversion coefficient form force/mass to acceleration
Real f_m2a;
/// displacements array
Array <Real> *displacement;
/// displacements array at the previous time step (used in finite deformation)
Array <Real> *previous_displacement;
/// lumped mass array
Array <Real> *mass;
/// velocities array
Array <Real> *velocity;
/// accelerations array
Array <Real> *acceleration;
/// accelerations array
Array <Real> *increment_acceleration;
/// forces array
Array <Real> *force;
/// residuals array
Array <Real> *residual;
/// array specifing if a degree of freedom is blocked or not
Array <bool> *blocked_dofs;
/// array of current position used during update residual
Array <Real> *current_position;
/// mass matrix
SparseMatrix *mass_matrix;
/// velocity damping matrix
SparseMatrix *velocity_damping_matrix;
/// stiffness matrix
SparseMatrix *stiffness_matrix;
/// jacobian matrix @f[A = cM + dD + K@f] with @f[c = \frac{1}{\beta \Delta
/// t^2}, d = \frac{\gamma}{\beta \Delta t} @f]
SparseMatrix *jacobian_matrix;
/// Arrays containing the material index for each element
ElementTypeMapArray<UInt> material_index;
/// Arrays containing the position in the element filter of the material (material's local numbering)
ElementTypeMapArray<UInt> material_local_numbering;
#ifdef SWIGPYTHON
public:
#endif
/// list of used materials
std::vector <Material *> materials;
/// mapping between material name and material internal id
std::map <std::string, UInt> materials_names_to_id;
#ifdef SWIGPYTHON
protected:
#endif
/// class defining of to choose a material
MaterialSelector *material_selector;
/// define if it is the default selector or not
bool is_default_material_selector;
/// integration scheme of second order used
IntegrationScheme2ndOrder *integrator;
/// increment of displacement
Array <Real> *increment;
/// flag defining if the increment must be computed or not
bool increment_flag;
/// solver for implicit
Solver *solver;
/// analysis method check the list in akantu::AnalysisMethod
AnalysisMethod method;
/// internal synchronizer for parallel computations
DistributedSynchronizer *synch_parallel;
/// tells if the material are instantiated
bool are_materials_instantiated;
/// map a registered internals to be flattened for dump purposes
std::map<std::pair<std::string,ElementKind>,ElementTypeMapArray<Real> *> registered_internals;
/// pointer to non-local manager: For non-local continuum damage computations
NonLocalManager * non_local_manager;
/// pointer to the pbc synchronizer
PBCSynchronizer * pbc_synch;
};
/* -------------------------------------------------------------------------- */
namespace BC {
namespace Neumann {
typedef FromHigherDim FromStress;
typedef FromSameDim FromTraction;
}
}
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "material.hh"
__BEGIN_AKANTU__
#include "solid_mechanics_model_tmpl.hh"
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "solid_mechanics_model_inline_impl.cc"
#endif
/// standard output stream operator
inline std::ostream & operator << (std::ostream & stream, const SolidMechanicsModel &_this) {
_this.printself(stream);
return stream;
}
__END_AKANTU__
#include "material_selector_tmpl.hh"
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
index c2fc756db..af86db504 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
@@ -1,650 +1,650 @@
/**
* @file fragment_manager.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Thu Jan 23 2014
- * @date last modification: Tue Aug 19 2014
+ * @date last modification: Mon Dec 14 2015
*
* @brief Group manager to handle fragments
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "fragment_manager.hh"
#include "material_cohesive.hh"
#include <numeric>
#include <algorithm>
#include <functional>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
FragmentManager::FragmentManager(SolidMechanicsModelCohesive & model,
bool dump_data,
const ID & id,
const MemoryID & memory_id) :
GroupManager(model.getMesh(), id, memory_id),
model(model),
mass_center(0, model.getSpatialDimension(), "mass_center"),
mass(0, model.getSpatialDimension(), "mass"),
velocity(0, model.getSpatialDimension(), "velocity"),
inertia_moments(0, model.getSpatialDimension(), "inertia_moments"),
principal_directions(0, model.getSpatialDimension() * model.getSpatialDimension(),
"principal_directions"),
quad_coordinates("quad_coordinates", id),
mass_density("mass_density", id),
nb_elements_per_fragment(0, 1, "nb_elements_per_fragment"),
dump_data(dump_data) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
/// compute quadrature points' coordinates
mesh.initElementTypeMapArray(quad_coordinates,
spatial_dimension,
spatial_dimension,
_not_ghost);
model.getFEEngine().interpolateOnIntegrationPoints(model.getMesh().getNodes(),
quad_coordinates);
/// store mass density per quadrature point
mesh.initElementTypeMapArray(mass_density,
1,
spatial_dimension,
_not_ghost);
storeMassDensityPerIntegrationPoint();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
class CohesiveElementFilter : public GroupManager::ClusteringFilter {
public:
CohesiveElementFilter(const SolidMechanicsModelCohesive & model,
const Real max_damage = 1.) :
model(model), is_unbroken(max_damage) {}
bool operator() (const Element & el) const {
if (el.kind == _ek_regular)
return true;
const Array<UInt> & mat_indexes = model.getMaterialByElement(el.type,
el.ghost_type);
const Array<UInt> & mat_loc_num = model.getMaterialLocalNumbering(el.type,
el.ghost_type);
const MaterialCohesive & mat
= static_cast<const MaterialCohesive &>
(model.getMaterial(mat_indexes(el.element)));
UInt el_index = mat_loc_num(el.element);
UInt nb_quad_per_element
= model.getFEEngine("CohesiveFEEngine").getNbIntegrationPoints(el.type, el.ghost_type);
const Array<Real> & damage_array = mat.getDamage(el.type, el.ghost_type);
AKANTU_DEBUG_ASSERT(nb_quad_per_element * el_index < damage_array.getSize(),
"This quadrature point is out of range");
const Real * element_damage
= damage_array.storage() + nb_quad_per_element * el_index;
UInt unbroken_quads = std::count_if(element_damage,
element_damage + nb_quad_per_element,
is_unbroken);
if (unbroken_quads > 0)
return true;
return false;
}
private:
struct IsUnbrokenFunctor {
IsUnbrokenFunctor(const Real & max_damage) : max_damage(max_damage) {}
bool operator() (const Real & x) {return x < max_damage;}
const Real max_damage;
};
const SolidMechanicsModelCohesive & model;
const IsUnbrokenFunctor is_unbroken;
};
/* -------------------------------------------------------------------------- */
void FragmentManager::buildFragments(Real damage_limit) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
DistributedSynchronizer * cohesive_synchronizer
= const_cast<DistributedSynchronizer *>(model.getCohesiveSynchronizer());
if (cohesive_synchronizer) {
cohesive_synchronizer->computeBufferSize(model, _gst_smmc_damage);
cohesive_synchronizer->asynchronousSynchronize(model, _gst_smmc_damage);
cohesive_synchronizer->waitEndSynchronize(model, _gst_smmc_damage);
}
#endif
DistributedSynchronizer & synchronizer
= const_cast<DistributedSynchronizer &>(model.getSynchronizer());
Mesh & mesh_facets = const_cast<Mesh &>(mesh.getMeshFacets());
UInt spatial_dimension = model.getSpatialDimension();
std::string fragment_prefix("fragment");
/// generate fragments
global_nb_fragment = createClusters(spatial_dimension,
fragment_prefix,
CohesiveElementFilter(model,
damage_limit),
&synchronizer,
&mesh_facets);
nb_fragment = getNbElementGroups(spatial_dimension);
fragment_index.resize(nb_fragment);
UInt * fragment_index_it = fragment_index.storage();
/// loop over fragments
for(const_element_group_iterator it(element_group_begin());
it != element_group_end(); ++it, ++fragment_index_it) {
/// get fragment index
std::string fragment_index_string
= it->first.substr(fragment_prefix.size() + 1);
std::stringstream sstr(fragment_index_string.c_str());
sstr >> *fragment_index_it;
AKANTU_DEBUG_ASSERT(!sstr.fail(), "fragment_index is not an integer");
}
/// compute fragments' mass
computeMass();
if (dump_data) {
createDumpDataArray(fragment_index, "fragments", true);
createDumpDataArray(mass, "fragments mass");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeMass() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
/// create a unit field per quadrature point, since to compute mass
/// it's neccessary to integrate only density
ElementTypeMapArray<Real> unit_field("unit_field", id);
mesh.initElementTypeMapArray(unit_field,
spatial_dimension,
spatial_dimension,
_not_ghost);
ElementTypeMapArray<Real>::type_iterator it = unit_field.firstType(spatial_dimension,
_not_ghost,
_ek_regular);
ElementTypeMapArray<Real>::type_iterator end = unit_field.lastType(spatial_dimension,
_not_ghost,
_ek_regular);
for (; it != end; ++it) {
ElementType type = *it;
Array<Real> & field_array = unit_field(type);
UInt nb_element = mesh.getNbElement(type);
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
field_array.resize(nb_element * nb_quad_per_element);
field_array.set(1.);
}
integrateFieldOnFragments(unit_field, mass);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeCenterOfMass() {
AKANTU_DEBUG_IN();
/// integrate position multiplied by density
integrateFieldOnFragments(quad_coordinates, mass_center);
/// divide it by the fragments' mass
Real * mass_storage = mass.storage();
Real * mass_center_storage = mass_center.storage();
UInt total_components = mass_center.getSize() * mass_center.getNbComponent();
for (UInt i = 0; i < total_components; ++i)
mass_center_storage[i] /= mass_storage[i];
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeVelocity() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
/// compute velocity per quadrature point
ElementTypeMapArray<Real> velocity_field("velocity_field", id);
mesh.initElementTypeMapArray(velocity_field,
spatial_dimension,
spatial_dimension,
_not_ghost);
model.getFEEngine().interpolateOnIntegrationPoints(model.getVelocity(),
velocity_field);
/// integrate on fragments
integrateFieldOnFragments(velocity_field, velocity);
/// divide it by the fragments' mass
Real * mass_storage = mass.storage();
Real * velocity_storage = velocity.storage();
UInt total_components = velocity.getSize() * velocity.getNbComponent();
for (UInt i = 0; i < total_components; ++i)
velocity_storage[i] /= mass_storage[i];
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Given the distance @f$ \mathbf{r} @f$ between a quadrature point
* and its center of mass, the moment of inertia is computed as \f[
* I_\mathrm{CM} = \mathrm{tr}(\mathbf{r}\mathbf{r}^\mathrm{T})
* \mathbf{I} - \mathbf{r}\mathbf{r}^\mathrm{T} \f] for more
* information check Wikipedia
* (http://en.wikipedia.org/wiki/Moment_of_inertia#Identities_for_a_skew-symmetric_matrix)
*
*/
void FragmentManager::computeInertiaMoments() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
computeCenterOfMass();
/// compute local coordinates products with respect to the center of match
ElementTypeMapArray<Real> moments_coords("moments_coords", id);
mesh.initElementTypeMapArray(moments_coords,
spatial_dimension * spatial_dimension,
spatial_dimension,
_not_ghost);
/// resize the by element type
ElementTypeMapArray<Real>::type_iterator it = moments_coords.firstType(spatial_dimension,
_not_ghost,
_ek_regular);
ElementTypeMapArray<Real>::type_iterator end = moments_coords.lastType(spatial_dimension,
_not_ghost,
_ek_regular);
for (; it != end; ++it) {
ElementType type = *it;
Array<Real> & field_array = moments_coords(type);
UInt nb_element = mesh.getNbElement(type);
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
field_array.resize(nb_element * nb_quad_per_element);
}
/// compute coordinates
Array<Real>::const_vector_iterator mass_center_it
= mass_center.begin(spatial_dimension);
/// loop over fragments
for(const_element_group_iterator it(element_group_begin());
it != element_group_end(); ++it, ++mass_center_it) {
const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
ElementTypeMapArray<UInt>::type_iterator type_it = el_list.firstType(spatial_dimension,
_not_ghost,
_ek_regular);
ElementTypeMapArray<UInt>::type_iterator type_end = el_list.lastType(spatial_dimension,
_not_ghost,
_ek_regular);
/// loop over elements of the fragment
for (; type_it != type_end; ++type_it) {
ElementType type = *type_it;
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
Array<Real> & moments_coords_array = moments_coords(type);
const Array<Real> & quad_coordinates_array = quad_coordinates(type);
const Array<UInt> & el_list_array = el_list(type);
Array<Real>::matrix_iterator moments_begin
= moments_coords_array.begin(spatial_dimension, spatial_dimension);
Array<Real>::const_vector_iterator quad_coordinates_begin
= quad_coordinates_array.begin(spatial_dimension);
Vector<Real> relative_coords(spatial_dimension);
for (UInt el = 0; el < el_list_array.getSize(); ++el) {
UInt global_el = el_list_array(el);
/// loop over quadrature points
for (UInt q = 0; q < nb_quad_per_element; ++q) {
UInt global_q = global_el * nb_quad_per_element + q;
Matrix<Real> moments_matrix = moments_begin[global_q];
const Vector<Real> & quad_coord_vector = quad_coordinates_begin[global_q];
/// to understand this read the documentation written just
/// before this function
relative_coords = quad_coord_vector;
relative_coords -= *mass_center_it;
moments_matrix.outerProduct(relative_coords, relative_coords);
Real trace = moments_matrix.trace();
moments_matrix *= -1.;
moments_matrix += Matrix<Real>::eye(spatial_dimension, trace);
}
}
}
}
/// integrate moments
Array<Real> integrated_moments(global_nb_fragment,
spatial_dimension * spatial_dimension);
integrateFieldOnFragments(moments_coords, integrated_moments);
/// compute and store principal moments
inertia_moments.resize(global_nb_fragment);
principal_directions.resize(global_nb_fragment);
Array<Real>::matrix_iterator integrated_moments_it
= integrated_moments.begin(spatial_dimension, spatial_dimension);
Array<Real>::vector_iterator inertia_moments_it
= inertia_moments.begin(spatial_dimension);
Array<Real>::matrix_iterator principal_directions_it
= principal_directions.begin(spatial_dimension, spatial_dimension);
for (UInt frag = 0; frag < global_nb_fragment; ++frag, ++integrated_moments_it,
++inertia_moments_it, ++principal_directions_it) {
integrated_moments_it->eig(*inertia_moments_it, *principal_directions_it);
}
if (dump_data)
createDumpDataArray(inertia_moments, "moments of inertia");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeAllData() {
AKANTU_DEBUG_IN();
buildFragments();
computeVelocity();
computeInertiaMoments();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::storeMassDensityPerIntegrationPoint() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator end = mesh.lastType(spatial_dimension);
for (; it != end; ++it) {
ElementType type = *it;
Array<Real> & mass_density_array = mass_density(type);
UInt nb_element = mesh.getNbElement(type);
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
mass_density_array.resize(nb_element * nb_quad_per_element);
const Array<UInt> & mat_indexes = model.getMaterialByElement(type);
Real * mass_density_it = mass_density_array.storage();
/// store mass_density for each element and quadrature point
for (UInt el = 0; el < nb_element; ++el) {
Material & mat = model.getMaterial(mat_indexes(el));
for (UInt q = 0; q < nb_quad_per_element; ++q, ++mass_density_it)
*mass_density_it = mat.getRho();
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::integrateFieldOnFragments(ElementTypeMapArray<Real> & field,
Array<Real> & output) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
UInt nb_component = output.getNbComponent();
/// integration part
output.resize(global_nb_fragment);
output.clear();
UInt * fragment_index_it = fragment_index.storage();
Array<Real>::vector_iterator output_begin = output.begin(nb_component);
/// loop over fragments
for(const_element_group_iterator it(element_group_begin());
it != element_group_end(); ++it, ++fragment_index_it) {
const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
ElementTypeMapArray<UInt>::type_iterator type_it = el_list.firstType(spatial_dimension,
_not_ghost,
_ek_regular);
ElementTypeMapArray<UInt>::type_iterator type_end = el_list.lastType(spatial_dimension,
_not_ghost,
_ek_regular);
/// loop over elements of the fragment
for (; type_it != type_end; ++type_it) {
ElementType type = *type_it;
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
const Array<Real> & density_array = mass_density(type);
Array<Real> & field_array = field(type);
const Array<UInt> & elements = el_list(type);
UInt nb_element = elements.getSize();
/// generate array to be integrated by filtering fragment's elements
Array<Real> integration_array(elements.getSize() * nb_quad_per_element,
nb_component);
Array<Real>::matrix_iterator int_array_it
= integration_array.begin_reinterpret(nb_quad_per_element,
nb_component, nb_element);
Array<Real>::matrix_iterator int_array_end
= integration_array.end_reinterpret(nb_quad_per_element,
nb_component, nb_element);
Array<Real>::matrix_iterator field_array_begin
= field_array.begin_reinterpret(nb_quad_per_element,
nb_component,
field_array.getSize() / nb_quad_per_element);
Array<Real>::const_vector_iterator density_array_begin
= density_array.begin_reinterpret(nb_quad_per_element,
density_array.getSize() / nb_quad_per_element);
for (UInt el = 0; int_array_it != int_array_end; ++int_array_it, ++el) {
UInt global_el = elements(el);
*int_array_it = field_array_begin[global_el];
/// multiply field by density
const Vector<Real> & density_vector = density_array_begin[global_el];
for (UInt i = 0; i < nb_quad_per_element; ++i) {
for (UInt j = 0; j < nb_component; ++j) {
(*int_array_it)(i, j) *= density_vector(i);
}
}
}
/// integrate the field over the fragment
Array<Real> integrated_array(elements.getSize(), nb_component);
model.getFEEngine().integrate(integration_array,
integrated_array,
nb_component,
type,
_not_ghost,
elements);
/// sum over all elements and store the result
Vector<Real> output_tmp(output_begin[*fragment_index_it]);
output_tmp += std::accumulate(integrated_array.begin(nb_component),
integrated_array.end(nb_component),
Vector<Real>(nb_component));
}
}
/// sum output over all processors
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
comm.allReduce(output.storage(), global_nb_fragment * nb_component, _so_sum);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeNbElementsPerFragment() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
nb_elements_per_fragment.resize(global_nb_fragment);
nb_elements_per_fragment.clear();
UInt * fragment_index_it = fragment_index.storage();
/// loop over fragments
for(const_element_group_iterator it(element_group_begin());
it != element_group_end(); ++it, ++fragment_index_it) {
const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
ElementTypeMapArray<UInt>::type_iterator type_it = el_list.firstType(spatial_dimension,
_not_ghost,
_ek_regular);
ElementTypeMapArray<UInt>::type_iterator type_end = el_list.lastType(spatial_dimension,
_not_ghost,
_ek_regular);
/// loop over elements of the fragment
for (; type_it != type_end; ++type_it) {
ElementType type = *type_it;
UInt nb_element = el_list(type).getSize();
nb_elements_per_fragment(*fragment_index_it) += nb_element;
}
}
/// sum values over all processors
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
comm.allReduce(nb_elements_per_fragment.storage(), global_nb_fragment, _so_sum);
if (dump_data)
createDumpDataArray(nb_elements_per_fragment, "elements per fragment");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename T>
void FragmentManager::createDumpDataArray(Array<T> & data,
std::string name,
bool fragment_index_output) {
AKANTU_DEBUG_IN();
if (data.getSize() == 0) return;
typedef typename Array<T>::vector_iterator data_iterator;
Mesh & mesh_not_const = const_cast<Mesh &>(mesh);
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_component = data.getNbComponent();
UInt * fragment_index_it = fragment_index.storage();
data_iterator data_begin = data.begin(nb_component);
/// loop over fragments
for(const_element_group_iterator it(element_group_begin());
it != element_group_end(); ++it, ++fragment_index_it) {
const ElementGroup & fragment = *(it->second);
/// loop over cluster types
ElementGroup::type_iterator type_it = fragment.firstType(spatial_dimension);
ElementGroup::type_iterator type_end = fragment.lastType(spatial_dimension);
for(; type_it != type_end; ++type_it) {
ElementType type = *type_it;
/// init mesh data
Array<T> * mesh_data
= mesh_not_const.getDataPointer<T>(name, type, _not_ghost, nb_component);
data_iterator mesh_data_begin = mesh_data->begin(nb_component);
ElementGroup::const_element_iterator el_it = fragment.element_begin(type);
ElementGroup::const_element_iterator el_end = fragment.element_end(type);
/// fill mesh data
if (fragment_index_output) {
for (; el_it != el_end; ++el_it) {
Vector<T> md_tmp(mesh_data_begin[*el_it]);
md_tmp(0) = *fragment_index_it;
}
} else {
for (; el_it != el_end; ++el_it) {
Vector<T> md_tmp(mesh_data_begin[*el_it]);
md_tmp = data_begin[*fragment_index_it];
}
}
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
index d285ef514..2c04d8eb2 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
@@ -1,174 +1,174 @@
/**
* @file fragment_manager.hh
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Thu Jan 23 2014
- * @date last modification: Tue Aug 19 2014
+ * @date last modification: Mon Dec 14 2015
*
* @brief Group manager to handle fragments
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_FRAGMENT_MANAGER_HH__
#define __AKANTU_FRAGMENT_MANAGER_HH__
#include "group_manager.hh"
#include "solid_mechanics_model_cohesive.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class FragmentManager : public GroupManager {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
FragmentManager(SolidMechanicsModelCohesive & model,
bool dump_data = true,
const ID & id = "fragment_manager",
const MemoryID & memory_id = 0);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
private:
/// store mass density per integration point
void storeMassDensityPerIntegrationPoint();
/// integrate an elemental field multiplied by density on global
/// fragments
void integrateFieldOnFragments(ElementTypeMapArray<Real> & field,
Array<Real> & output);
/// compute fragments' mass
void computeMass();
/// create dump data for a single array
template <typename T>
void createDumpDataArray(Array<T> & data,
std::string name,
bool fragment_index_output = false);
public:
/// build fragment list (cohesive elements are considered broken if
/// damage >= damage_limit)
void buildFragments(Real damage_limit = 1.);
/// compute fragments' center of mass
void computeCenterOfMass();
/// compute fragments' velocity
void computeVelocity();
/// computes principal moments of inertia with respect to the center
/// of mass of each fragment
void computeInertiaMoments();
/// compute all fragments' data
void computeAllData();
/// compute number of elements per fragment
void computeNbElementsPerFragment();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get number of fragments
AKANTU_GET_MACRO(NbFragment, global_nb_fragment, UInt);
/// get fragments' mass
AKANTU_GET_MACRO(Mass, mass, const Array<Real> &);
/// get fragments' center of mass
AKANTU_GET_MACRO(CenterOfMass, mass_center, const Array<Real> &);
/// get fragments' velocity
AKANTU_GET_MACRO(Velocity, velocity, const Array<Real> &);
/// get fragments' principal moments of inertia
AKANTU_GET_MACRO(MomentsOfInertia, inertia_moments, const Array<Real> &);
/// get fragments' principal directions
AKANTU_GET_MACRO(PrincipalDirections, principal_directions, const Array<Real> &);
/// get number of elements per fragment
AKANTU_GET_MACRO(NbElementsPerFragment,
nb_elements_per_fragment, const Array<UInt> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// local_fragment index
Array<UInt> fragment_index;
/// global number of fragments (parallel simulations)
UInt global_nb_fragment;
/// number of fragments
UInt nb_fragment;
/// cohesive solid mechanics model associated
SolidMechanicsModelCohesive & model;
/// fragments' center of mass
Array<Real> mass_center;
/// fragments' mass
Array<Real> mass;
/// fragments' velocity
Array<Real> velocity;
/// fragments' principal moments of inertia with respect to the
/// center of mass
Array<Real> inertia_moments;
/// fragments' principal directions
Array<Real> principal_directions;
/// quadrature points' coordinates
ElementTypeMapArray<Real> quad_coordinates;
/// mass density per quadrature point
ElementTypeMapArray<Real> mass_density;
/// fragment filter
Array<UInt> nb_elements_per_fragment;
/// dump data
bool dump_data;
};
__END_AKANTU__
#endif /* __AKANTU_FRAGMENT_MANAGER_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
index db65caf9c..ee723cbe4 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
@@ -1,95 +1,96 @@
/**
* @file material_selector_cohesive.cc
*
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Mauro Corrado <mauro.corrado@epfl.ch>
-
- * @date Thu Dec 10 10:27:02 2015
*
- * @brief
+ * @date creation: Fri Dec 11 2015
+ * @date last modification: Mon Dec 14 2015
+ *
+ * @brief Material selector for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_selector_cohesive.hh"
#include "solid_mechanics_model_cohesive.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
DefaultMaterialCohesiveSelector::DefaultMaterialCohesiveSelector(
const SolidMechanicsModelCohesive &model)
: DefaultMaterialSelector(model.getMaterialByElement()),
facet_material(model.getFacetMaterial()), mesh(model.getMesh()) {}
/* -------------------------------------------------------------------------- */
UInt DefaultMaterialCohesiveSelector::operator()(const Element &element) {
if (Mesh::getKind(element.type) == _ek_cohesive) {
try {
const Array<Element> &cohesive_el_to_facet =
mesh.getMeshFacets().getSubelementToElement(element.type,
element.ghost_type);
bool third_dimension = (mesh.getSpatialDimension() == 3);
const Element &facet =
cohesive_el_to_facet(element.element, third_dimension);
if (facet_material.exists(facet.type, facet.ghost_type)) {
return facet_material(facet.type, facet.ghost_type)(facet.element);
} else {
return MaterialSelector::operator()(element);
}
} catch (...) {
return MaterialSelector::operator()(element);
}
} else if (Mesh::getSpatialDimension(element.type) ==
mesh.getSpatialDimension() - 1) {
return facet_material(element.type, element.ghost_type)(element.element);
} else {
return DefaultMaterialSelector::operator()(element);
}
}
/* -------------------------------------------------------------------------- */
MeshDataMaterialCohesiveSelector::MeshDataMaterialCohesiveSelector(
const SolidMechanicsModelCohesive &model)
: MeshDataMaterialSelector<std::string>("physical_names", model),
mesh_facets(model.getMeshFacets()),
material_index(mesh_facets.getData<UInt>("physical_names")) {
third_dimension = (model.getSpatialDimension() == 3);
}
/* -------------------------------------------------------------------------- */
UInt MeshDataMaterialCohesiveSelector::operator()(const Element &element) {
if (element.kind == _ek_cohesive) {
const Array<Element> &cohesive_el_to_facet =
mesh_facets.getSubelementToElement(element.type, element.ghost_type);
const Element &facet =
cohesive_el_to_facet(element.element, third_dimension);
UInt material_id =
material_index(facet.type, facet.ghost_type)(facet.element);
return material_id;
}
else
return MeshDataMaterialSelector<std::string>::operator()(element);
}
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
index 5f1580248..8d423a4b9 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
@@ -1,76 +1,76 @@
/**
* @file material_selector_cohesive.hh
*
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date creation: Tue May 08 2012
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Dec 11 2015
+ * @date last modification: Mon Dec 14 2015
*
* @brief Material selectors for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_selector.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class SolidMechanicsModelCohesive;
}
__BEGIN_AKANTU__
#ifndef __AKANTU_MATERIAL_SELECTOR_COHESIVE_HH__
#define __AKANTU_MATERIAL_SELECTOR_COHESIVE_HH__
/* -------------------------------------------------------------------------- */
/**
* class that assigns the first cohesive material by default to the
* cohesive elements
*/
class DefaultMaterialCohesiveSelector : public DefaultMaterialSelector {
public:
DefaultMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model);
virtual UInt operator()(const Element & element);
private:
const ElementTypeMapArray<UInt> & facet_material;
const Mesh & mesh;
};
/* -------------------------------------------------------------------------- */
/// To be used with intrinsic elements inserted along mesh physical surfaces
class MeshDataMaterialCohesiveSelector
: public MeshDataMaterialSelector<std::string> {
public:
MeshDataMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model);
virtual UInt operator()(const Element & element);
protected:
const Mesh &mesh_facets;
const ElementTypeMapArray<UInt> & material_index;
bool third_dimension;
};
#endif /* __AKANTU_MATERIAL_SELECTOR_COHESIVE_HH__ */
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
index 335153da2..e98f8f154 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
@@ -1,751 +1,753 @@
/**
* @file solid_mechanics_model_cohesive.cc
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Wed Jan 13 2016
*
* @brief Solid mechanics model for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <algorithm>
#include "shape_cohesive.hh"
#include "solid_mechanics_model_cohesive.hh"
#include "dumpable_inline_impl.hh"
#include "material_cohesive.hh"
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const SolidMechanicsModelCohesiveOptions default_solid_mechanics_model_cohesive_options(_explicit_lumped_mass,
false,
false);
/* -------------------------------------------------------------------------- */
SolidMechanicsModelCohesive::SolidMechanicsModelCohesive(Mesh & mesh,
UInt dim,
const ID & id,
const MemoryID & memory_id) :
SolidMechanicsModel(mesh, dim, id, memory_id),
tangents("tangents", id),
facet_stress("facet_stress", id),
facet_material("facet_material", id) {
AKANTU_DEBUG_IN();
inserter = NULL;
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
facet_synchronizer = NULL;
facet_stress_synchronizer = NULL;
cohesive_distributed_synchronizer = NULL;
global_connectivity = NULL;
#endif
delete material_selector;
material_selector = new DefaultMaterialCohesiveSelector(*this);
this->registerEventHandler(*this);
#if defined(AKANTU_USE_IOHELPER)
this->mesh.registerDumper<DumperParaview>("cohesive elements", id);
this->mesh.addDumpMeshToDumper("cohesive elements",
mesh, spatial_dimension, _not_ghost, _ek_cohesive);
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SolidMechanicsModelCohesive::~SolidMechanicsModelCohesive() {
AKANTU_DEBUG_IN();
delete inserter;
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
delete cohesive_distributed_synchronizer;
delete facet_synchronizer;
delete facet_stress_synchronizer;
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::setTimeStep(Real time_step) {
SolidMechanicsModel::setTimeStep(time_step);
#if defined(AKANTU_USE_IOHELPER)
this->mesh.getDumper("cohesive elements").setTimeStep(time_step);
#endif
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initFull(const ModelOptions & options) {
AKANTU_DEBUG_IN();
const SolidMechanicsModelCohesiveOptions & smmc_options =
dynamic_cast<const SolidMechanicsModelCohesiveOptions &>(options);
this->is_extrinsic = smmc_options.extrinsic;
if (!inserter)
inserter = new CohesiveElementInserter(mesh, is_extrinsic, synch_parallel,
id+":cohesive_element_inserter");
SolidMechanicsModel::initFull(options);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initMaterials() {
AKANTU_DEBUG_IN();
// make sure the material are instantiated
if(!are_materials_instantiated) instantiateMaterials();
/// find the first cohesive material
UInt cohesive_index = 0;
while ((dynamic_cast<MaterialCohesive *>(materials[cohesive_index]) == NULL)
&& cohesive_index <= materials.size())
++cohesive_index;
AKANTU_DEBUG_ASSERT(cohesive_index != materials.size(),
"No cohesive materials in the material input file");
material_selector->setFallback(cohesive_index);
// set the facet information in the material in case of dynamic insertion
if (is_extrinsic) {
const Mesh & mesh_facets = inserter->getMeshFacets();
mesh_facets.initElementTypeMapArray(facet_material, 1, spatial_dimension - 1);
Element element;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
element.ghost_type = *gt;
Mesh::type_iterator first = mesh_facets.firstType(spatial_dimension - 1, *gt);
Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1, *gt);
for(;first != last; ++first) {
element.type = *first;
Array<UInt> & f_material = facet_material(*first, *gt);
UInt nb_element = mesh_facets.getNbElement(*first, *gt);
f_material.resize(nb_element);
f_material.set(cohesive_index);
for (UInt el = 0; el < nb_element; ++el) {
element.element = el;
UInt mat_index = (*material_selector)(element);
f_material(el) = mat_index;
MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(*materials[mat_index]);
mat.addFacet(element);
}
}
}
SolidMechanicsModel::initMaterials();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
if (facet_synchronizer != NULL)
inserter->initParallel(facet_synchronizer, synch_parallel);
#endif
initAutomaticInsertion();
} else {
// TODO think of something a bit mor consistant than just coding the first
// thing that comes in Fabian's head....
typedef ParserSection::const_section_iterator const_section_iterator;
std::pair<const_section_iterator, const_section_iterator> sub_sections =
this->parser->getSubSections(_st_mesh);
if (sub_sections.first != sub_sections.second) {
std::string cohesive_surfaces =
sub_sections.first->getParameter("cohesive_surfaces");
this->initIntrinsicCohesiveMaterials(cohesive_surfaces);
} else {
this->initIntrinsicCohesiveMaterials(cohesive_index);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(std::string cohesive_surfaces) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
if (facet_synchronizer != NULL)
inserter->initParallel(facet_synchronizer, synch_parallel);
#endif
std::istringstream split(cohesive_surfaces);
std::string physname;
while(std::getline(split,physname,',')){
AKANTU_DEBUG_INFO("Pre-inserting cohesive elements along facets from physical surface: "
<< physname);
insertElementsFromMeshData(physname);
}
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
if (facet_synchronizer != NULL){
facet_synchronizer-> asynchronousSynchronize(*inserter, _gst_ce_groups);
facet_synchronizer-> waitEndSynchronize(*inserter, _gst_ce_groups);
}
#endif
SolidMechanicsModel::initMaterials();
if(is_default_material_selector) delete material_selector;
material_selector = new MeshDataMaterialCohesiveSelector(*this);
inserter->insertElements();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(UInt cohesive_index) {
AKANTU_DEBUG_IN();
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
Mesh::type_iterator first = mesh.firstType(spatial_dimension, *gt, _ek_cohesive);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, *gt, _ek_cohesive);
for(;first != last; ++first) {
Array<UInt> & mat_indexes = this->material_index(*first, *gt);
Array<UInt> & mat_loc_num = this->material_local_numbering(*first, *gt);
mat_indexes.set(cohesive_index);
mat_loc_num.clear();
}
}
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
if (facet_synchronizer != NULL)
inserter->initParallel(facet_synchronizer, synch_parallel);
#endif
SolidMechanicsModel::initMaterials();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Initialize the model,basically it pre-compute the shapes, shapes derivatives
* and jacobian
*
*/
void SolidMechanicsModelCohesive::initModel() {
AKANTU_DEBUG_IN();
SolidMechanicsModel::initModel();
registerFEEngineObject<MyFEEngineCohesiveType>("CohesiveFEEngine", mesh, spatial_dimension);
/// add cohesive type connectivity
ElementType type = _not_defined;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType type_ghost = *gt;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, type_ghost);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, type_ghost);
for (; it != last; ++it) {
const Array<UInt> & connectivity = mesh.getConnectivity(*it, type_ghost);
if (connectivity.getSize() != 0) {
type = *it;
ElementType type_facet = Mesh::getFacetType(type);
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
mesh.addConnectivityType(type_cohesive, type_ghost);
}
}
}
AKANTU_DEBUG_ASSERT(type != _not_defined, "No elements in the mesh");
getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
registerFEEngineObject<MyFEEngineType>("FacetsFEEngine",
mesh.getMeshFacets(),
spatial_dimension - 1);
if (is_extrinsic) {
getFEEngine("FacetsFEEngine").initShapeFunctions(_not_ghost);
getFEEngine("FacetsFEEngine").initShapeFunctions(_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::limitInsertion(BC::Axis axis,
Real first_limit,
Real second_limit) {
AKANTU_DEBUG_IN();
inserter->setLimit(axis, first_limit, second_limit);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::insertIntrinsicElements() {
AKANTU_DEBUG_IN();
inserter->insertIntrinsicElements();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::insertElementsFromMeshData(std::string physname) {
AKANTU_DEBUG_IN();
UInt material_index = SolidMechanicsModel::getMaterialIndex(physname);
inserter->insertIntrinsicElements(physname, material_index);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initAutomaticInsertion() {
AKANTU_DEBUG_IN();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
if (facet_stress_synchronizer != NULL) {
DataAccessor * data_accessor = this;
const ElementTypeMapArray<UInt> & rank_to_element = synch_parallel->getPrankToElement();
facet_stress_synchronizer->updateFacetStressSynchronizer(*inserter,
rank_to_element,
*data_accessor);
}
#endif
inserter->getMeshFacets().initElementTypeMapArray(facet_stress,
2 * spatial_dimension * spatial_dimension,
spatial_dimension - 1);
resizeFacetStress();
/// compute normals on facets
computeNormals();
initStressInterpolation();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::updateAutomaticInsertion() {
AKANTU_DEBUG_IN();
inserter->limitCheckFacets();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
if (facet_stress_synchronizer != NULL) {
DataAccessor * data_accessor = this;
const ElementTypeMapArray<UInt> & rank_to_element = synch_parallel->getPrankToElement();
facet_stress_synchronizer->updateFacetStressSynchronizer(*inserter,
rank_to_element,
*data_accessor);
}
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initStressInterpolation() {
Mesh & mesh_facets = inserter->getMeshFacets();
/// compute quadrature points coordinates on facets
Array<Real> & position = mesh.getNodes();
ElementTypeMapArray<Real> quad_facets("quad_facets", id);
mesh_facets.initElementTypeMapArray(quad_facets,
spatial_dimension, spatial_dimension - 1);
getFEEngine("FacetsFEEngine").interpolateOnIntegrationPoints(position, quad_facets);
/// compute elements quadrature point positions and build
/// element-facet quadrature points data structure
ElementTypeMapArray<Real> elements_quad_facets("elements_quad_facets", id);
mesh.initElementTypeMapArray(elements_quad_facets,
spatial_dimension,
spatial_dimension);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType elem_gt = *gt;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, elem_gt);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, elem_gt);
for (; it != last; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type, elem_gt);
if (nb_element == 0) continue;
/// compute elements' quadrature points and list of facet
/// quadrature points positions by element
Array<Element> & facet_to_element = mesh_facets.getSubelementToElement(type,
elem_gt);
UInt nb_facet_per_elem = facet_to_element.getNbComponent();
Array<Real> & el_q_facet = elements_quad_facets(type, elem_gt);
ElementType facet_type = Mesh::getFacetType(type);
UInt nb_quad_per_facet =
getFEEngine("FacetsFEEngine").getNbIntegrationPoints(facet_type);
el_q_facet.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet);
for (UInt el = 0; el < nb_element; ++el) {
for (UInt f = 0; f < nb_facet_per_elem; ++f) {
Element global_facet_elem = facet_to_element(el, f);
UInt global_facet = global_facet_elem.element;
GhostType facet_gt = global_facet_elem.ghost_type;
const Array<Real> & quad_f = quad_facets(facet_type, facet_gt);
for (UInt q = 0; q < nb_quad_per_facet; ++q) {
for (UInt s = 0; s < spatial_dimension; ++s) {
el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet
+ f * nb_quad_per_facet + q, s)
= quad_f(global_facet * nb_quad_per_facet + q, s);
}
}
}
}
}
}
/// loop over non cohesive materials
for (UInt m = 0; m < materials.size(); ++m) {
try {
MaterialCohesive & mat __attribute__((unused)) =
dynamic_cast<MaterialCohesive &>(*materials[m]);
} catch(std::bad_cast&) {
/// initialize the interpolation function
materials[m]->initElementalFieldInterpolation(elements_quad_facets);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::updateResidual(bool need_initialize) {
AKANTU_DEBUG_IN();
if (need_initialize) initializeUpdateResidualData();
// f -= fint
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
try {
MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(**mat_it);
mat.computeTraction(_not_ghost);
} catch (std::bad_cast & bce) { }
}
SolidMechanicsModel::updateResidual(false);
if (isExplicit()){
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
try {
MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(**mat_it);
mat.computeEnergies();
} catch (std::bad_cast & bce) { }
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::computeNormals() {
AKANTU_DEBUG_IN();
Mesh & mesh_facets = this->inserter->getMeshFacets();
this->getFEEngine("FacetsFEEngine").computeNormalsOnIntegrationPoints(_not_ghost);
/**
* @todo store tangents while computing normals instead of
* recomputing them as follows:
*/
/* ------------------------------------------------------------------------ */
UInt tangent_components = spatial_dimension * (spatial_dimension - 1);
mesh_facets.initElementTypeMapArray(tangents,
tangent_components,
spatial_dimension - 1);
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1);
Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1);
for (; it != last; ++it) {
ElementType facet_type = *it;
const Array<Real> & normals =
this->getFEEngine("FacetsFEEngine").getNormalsOnIntegrationPoints(facet_type);
Array<Real> & tangents = this->tangents(facet_type);
Math::compute_tangents(normals, tangents);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::interpolateStress() {
ElementTypeMapArray<Real> by_elem_result("temporary_stress_by_facets", id);
for (UInt m = 0; m < materials.size(); ++m) {
try {
MaterialCohesive & mat __attribute__((unused)) =
dynamic_cast<MaterialCohesive &>(*materials[m]);
} catch(std::bad_cast&) {
/// interpolate stress on facet quadrature points positions
materials[m]->interpolateStressOnFacets(facet_stress, by_elem_result);
}
}
#if defined(AKANTU_DEBUG_TOOLS)
debug::element_manager.printData(debug::_dm_model_cohesive,
"Interpolated stresses before",
facet_stress);
#endif
synch_registry->synchronize(_gst_smmc_facets_stress);
#if defined(AKANTU_DEBUG_TOOLS)
debug::element_manager.printData(debug::_dm_model_cohesive,
"Interpolated stresses",
facet_stress);
#endif
}
/* -------------------------------------------------------------------------- */
UInt SolidMechanicsModelCohesive::checkCohesiveStress() {
interpolateStress();
for (UInt m = 0; m < materials.size(); ++m) {
try {
MaterialCohesive & mat_cohesive = dynamic_cast<MaterialCohesive &>(*materials[m]);
/// check which not ghost cohesive elements are to be created
mat_cohesive.checkInsertion();
} catch(std::bad_cast&) { }
}
/* if(static and extrinsic) {
check max mean stresses
and change inserter.getInsertionFacets(type_facet);
}
*/
/// communicate data among processors
synch_registry->synchronize(_gst_smmc_facets);
/// insert cohesive elements
return inserter->insertElements();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
updateCohesiveSynchronizers();
#endif
SolidMechanicsModel::onElementsAdded(element_list, event);
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
if (cohesive_distributed_synchronizer != NULL)
cohesive_distributed_synchronizer->computeAllBufferSizes(*this);
#endif
/// update shape functions
getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
if (is_extrinsic) resizeFacetStress();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::onNodesAdded(const Array<UInt> & doubled_nodes,
__attribute__((unused)) const NewNodesEvent & event) {
AKANTU_DEBUG_IN();
UInt nb_new_nodes = doubled_nodes.getSize();
Array<UInt> nodes_list(nb_new_nodes);
for (UInt n = 0; n < nb_new_nodes; ++n)
nodes_list(n) = doubled_nodes(n, 1);
SolidMechanicsModel::onNodesAdded(nodes_list, event);
for (UInt n = 0; n < nb_new_nodes; ++n) {
UInt old_node = doubled_nodes(n, 0);
UInt new_node = doubled_nodes(n, 1);
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
(*displacement)(new_node, dim) = (*displacement)(old_node, dim);
(*velocity) (new_node, dim) = (*velocity) (old_node, dim);
(*acceleration)(new_node, dim) = (*acceleration)(old_node, dim);
(*blocked_dofs)(new_node, dim) = (*blocked_dofs)(old_node, dim);
if (current_position)
(*current_position)(new_node, dim) = (*current_position)(old_node, dim);
if (increment_acceleration)
(*increment_acceleration)(new_node, dim)
= (*increment_acceleration)(old_node, dim);
if (increment)
(*increment)(new_node, dim) = (*increment)(old_node, dim);
if (previous_displacement)
(*previous_displacement)(new_node, dim)
= (*previous_displacement)(old_node, dim);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::onEndSolveStep(const AnalysisMethod & method) {
AKANTU_DEBUG_IN();
/******************************************************************************
This is required because the Cauchy stress is the stress measure that is used
to check the insertion of cohesive elements
******************************************************************************/
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
if(mat.isFiniteDeformation())
mat.computeAllCauchyStresses(_not_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "SolidMechanicsModelCohesive [" << std::endl;
SolidMechanicsModel::printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::resizeFacetStress() {
AKANTU_DEBUG_IN();
Mesh & mesh_facets = inserter->getMeshFacets();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end();
++gt) {
GhostType ghost_type = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
UInt nb_quadrature_points =
getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type, ghost_type);
UInt new_size = nb_facet * nb_quadrature_points;
facet_stress(type, ghost_type).resize(new_size);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = this->spatial_dimension;
ElementKind _element_kind = element_kind;
if (dumper_name == "cohesive elements") {
_element_kind = _ek_cohesive;
} else if (dumper_name == "facets") {
spatial_dimension = this->spatial_dimension - 1;
}
SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name,
field_id,
group_name,
spatial_dimension,
_element_kind,
padding_flag);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::onDump(){
this->flattenAllRegisteredInternals(_ek_cohesive);
SolidMechanicsModel::onDump();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
index cd3bbee92..25df8af48 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
@@ -1,260 +1,262 @@
/**
* @file solid_mechanics_model_cohesive.hh
*
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Mon Dec 14 2015
*
* @brief Solid mechanics model for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__
#include "solid_mechanics_model.hh"
#include "solid_mechanics_model_event_handler.hh"
#include "cohesive_element_inserter.hh"
#include "material_selector_cohesive.hh"
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
# include "facet_synchronizer.hh"
# include "facet_stress_synchronizer.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
struct SolidMechanicsModelCohesiveOptions : public SolidMechanicsModelOptions {
SolidMechanicsModelCohesiveOptions(AnalysisMethod analysis_method = _explicit_lumped_mass,
bool extrinsic = false,
bool no_init_materials = false) :
SolidMechanicsModelOptions(analysis_method, no_init_materials),
extrinsic(extrinsic) {}
bool extrinsic;
};
extern const SolidMechanicsModelCohesiveOptions default_solid_mechanics_model_cohesive_options;
/* -------------------------------------------------------------------------- */
/* Solid Mechanics Model for Cohesive elements */
/* -------------------------------------------------------------------------- */
class SolidMechanicsModelCohesive : public SolidMechanicsModel,
public SolidMechanicsModelEventHandler{
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
class NewCohesiveNodesEvent : public NewNodesEvent {
public:
AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
protected:
Array<UInt> old_nodes;
};
typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive> MyFEEngineCohesiveType;
SolidMechanicsModelCohesive(Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "solid_mechanics_model_cohesive",
const MemoryID & memory_id = 0);
virtual ~SolidMechanicsModelCohesive();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// set the value of the time step
void setTimeStep(Real time_step);
/// assemble the residual for the explicit scheme
virtual void updateResidual(bool need_initialize = true);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/// function to perform a stress check on each facet and insert
/// cohesive elements if needed (returns the number of new cohesive
/// elements)
UInt checkCohesiveStress();
/// interpolate stress on facets
void interpolateStress();
/// initialize the cohesive model
void initFull(const ModelOptions & options = default_solid_mechanics_model_cohesive_options);
/// initialize the model
void initModel();
/// initialize cohesive material
void initMaterials();
/// init facet filters for cohesive materials
void initFacetFilter();
/// limit the cohesive element insertion to a given area
void limitInsertion(BC::Axis axis, Real first_limit, Real second_limit);
/// update automatic insertion after a change in the element inserter
void updateAutomaticInsertion();
/// insert intrinsic cohesive elements
void insertIntrinsicElements();
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool solveStepCohesive(Real tolerance,
Real & error,
UInt max_iteration = 100,
bool load_reduction = false,
Real tol_increase_factor = 1.0,
bool do_not_factorize = false);
/// initialize stress interpolation
void initStressInterpolation();
private:
/// initialize cohesive material with intrinsic insertion (by default)
void initIntrinsicCohesiveMaterials(UInt cohesive_index);
/// initialize cohesive material with intrinsic insertion (if physical surfaces are precised)
void initIntrinsicCohesiveMaterials(std::string cohesive_surfaces);
/// insert cohesive elements along a given physical surface of the mesh
void insertElementsFromMeshData(std::string physical_name);
/// initialize completely the model for extrinsic elements
void initAutomaticInsertion();
/// compute facets' normals
void computeNormals();
/// resize facet stress
void resizeFacetStress();
/// init facets_check array
void initFacetsCheck();
/* ------------------------------------------------------------------------ */
/* Mesh Event Handler inherited members */
/* ------------------------------------------------------------------------ */
protected:
virtual void onNodesAdded (const Array<UInt> & nodes_list,
const NewNodesEvent & event);
virtual void onElementsAdded (const Array<Element> & nodes_list,
const NewElementsEvent & event);
/* ------------------------------------------------------------------------ */
/* SolidMechanicsModelEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
virtual void onEndSolveStep(const AnalysisMethod & method);
/* ------------------------------------------------------------------------ */
/* Dumpable interface */
/* ------------------------------------------------------------------------ */
public:
virtual void onDump();
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get facet mesh
AKANTU_GET_MACRO(MeshFacets, mesh.getMeshFacets(), const Mesh &);
/// get stress on facets vector
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(StressOnFacets, facet_stress, Real);
/// get facet material
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetMaterial, facet_material, UInt);
/// get facet material
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetMaterial, facet_material, UInt);
/// get facet material
AKANTU_GET_MACRO(FacetMaterial, facet_material, const ElementTypeMapArray<UInt> &);
/// @todo THIS HAS TO BE CHANGED
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Tangents, tangents, Real);
/// get element inserter
AKANTU_GET_MACRO_NOT_CONST(ElementInserter, *inserter, CohesiveElementInserter &);
/// get is_extrinsic boolean
AKANTU_GET_MACRO(IsExtrinsic, is_extrinsic, bool);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// @todo store tangents when normals are computed:
ElementTypeMapArray<Real> tangents;
/// stress on facets on the two sides by quadrature point
ElementTypeMapArray<Real> facet_stress;
/// material to use if a cohesive element is created on a facet
ElementTypeMapArray<UInt> facet_material;
bool is_extrinsic;
/// cohesive element inserter
CohesiveElementInserter * inserter;
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
#include "solid_mechanics_model_cohesive_parallel.hh"
#endif
};
/* -------------------------------------------------------------------------- */
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const SolidMechanicsModelCohesive & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#include "solid_mechanics_model_cohesive_inline_impl.cc"
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
index c3393e80a..7b0610c3e 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
@@ -1,304 +1,306 @@
/**
* @file solid_mechanics_model_cohesive_inline_impl.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date Thu Feb 26 14:23:45 2015
+ * @date creation: Fri Jan 18 2013
+ * @date last modification: Thu Jan 14 2016
*
* @brief Implementation of inline functions for the Cohesive element model
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include <algorithm>
#include "material_cohesive.hh"
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__
#define __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool SolidMechanicsModelCohesive::solveStepCohesive(Real tolerance,
Real & error,
UInt max_iteration,
bool load_reduction,
Real tol_increase_factor,
bool do_not_factorize) {
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
this->implicitPred();
bool insertion_new_element = true;
bool converged = false;
Array<Real> * displacement_tmp = NULL;
Array<Real> * velocity_tmp = NULL;
Array<Real> * acceleration_tmp = NULL;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int prank = comm.whoAmI();
/// Loop for the insertion of new cohesive elements
while (insertion_new_element) {
if (is_extrinsic) {
/// If in extrinsic the solution of the previous incremental
/// step is saved in temporary arrays created for displacements,
/// velocities and accelerations. Such arrays are used to find
/// the solution with the Newton-Raphson scheme (this is done by
/// pointing the pointer "displacement" to displacement_tmp). In
/// this way, inside the array "displacement" is kept the
/// solution of the previous incremental step, and in
/// "displacement_tmp" is saved the current solution.
Array<Real> * tmp_swap;
if(!displacement_tmp) {
displacement_tmp = new Array<Real>(*(this->displacement));
} else {
displacement_tmp->resize(this->displacement->getSize());
displacement_tmp->copy(*(this->displacement));
}
tmp_swap = displacement_tmp;
displacement_tmp = this->displacement;
this->displacement = tmp_swap;
if(!velocity_tmp) {
velocity_tmp = new Array<Real>(*(this->velocity));
} else {
velocity_tmp->resize(this->velocity->getSize());
velocity_tmp->copy(*(this->velocity));
}
tmp_swap = velocity_tmp;
velocity_tmp = this->velocity;
this->velocity = tmp_swap;
if(!acceleration_tmp) {
acceleration_tmp = new Array<Real>(*(this->acceleration));
} else {
acceleration_tmp->resize(this->acceleration->getSize());
acceleration_tmp->copy(*(this->acceleration));
}
tmp_swap = acceleration_tmp;
acceleration_tmp = this->acceleration;
this->acceleration = tmp_swap;
}
this->updateResidual();
AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
"You should first initialize the implicit solver and assemble the stiffness matrix");
bool need_factorize = !do_not_factorize;
if (method ==_implicit_dynamic) {
AKANTU_DEBUG_ASSERT(mass_matrix != NULL,
"You should first initialize the implicit solver and assemble the mass matrix");
}
switch (cmethod) {
case _scm_newton_raphson_tangent:
case _scm_newton_raphson_tangent_not_computed:
break;
case _scm_newton_raphson_tangent_modified:
this->assembleStiffnessMatrix();
break;
default:
AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
}
UInt iter = 0;
converged = false;
error = 0.;
if(criteria == _scc_residual) {
converged = this->testConvergence<criteria> (tolerance, error);
if(converged) return converged;
}
/// Loop to solve the nonlinear system
do {
if (cmethod == _scm_newton_raphson_tangent)
this->assembleStiffnessMatrix();
solve<NewmarkBeta::_displacement_corrector> (*increment, 1., need_factorize);
this->implicitCorr();
this->updateResidual();
converged = this->testConvergence<criteria> (tolerance, error);
iter++;
AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration "
<< std::setw(std::log10(max_iteration)) << iter
<< ": error " << error << (converged ? " < " : " > ") << tolerance);
switch (cmethod) {
case _scm_newton_raphson_tangent:
need_factorize = true;
break;
case _scm_newton_raphson_tangent_not_computed:
case _scm_newton_raphson_tangent_modified:
need_factorize = false;
break;
default:
AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
}
} while (!converged && iter < max_iteration);
/// This is to save the obtained result and proceed with the
/// simulation even if the error is higher than the pre-fixed
/// tolerance. This is done only after loading reduction
/// (load_reduction = true).
if (load_reduction && (error < tolerance * tol_increase_factor)) converged = true;
if (converged) {
// EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
// !!! add sendEvent to call computeCauchyStress !!!!
if (prank==0){
std::cout << "Error after convergence: " << error << std::endl;
std::cout << "no. of iterations: " << iter << std::endl;
}
} else if(iter == max_iteration) {
if (prank==0){
AKANTU_DEBUG_WARNING("[" << criteria << "] Convergence not reached after "
<< std::setw(std::log10(max_iteration)) << iter <<
" iteration" << (iter == 1 ? "" : "s") << "!" << std::endl);
std::cout << "Error after NON convergence: " << error << std::endl;
}
}
if (is_extrinsic) {
/// If is extrinsic the pointer "displacement" is moved back to
/// the array displacement. In this way, the array displacement
/// is correctly resized during the checkCohesiveStress function
/// (in case new cohesive elements are added). This is possible
/// because the procedure called by checkCohesiveStress does not
/// use the displacement field (the correct one is now stored in
/// displacement_tmp), but directly the stress field that is
/// already computed.
Array<Real> * tmp_swap;
tmp_swap = displacement_tmp;
displacement_tmp = this->displacement;
this->displacement = tmp_swap;
tmp_swap = velocity_tmp;
velocity_tmp = this->velocity;
this->velocity = tmp_swap;
tmp_swap = acceleration_tmp;
acceleration_tmp = this->acceleration;
this->acceleration = tmp_swap;
/// If convergence is reached, call checkCohesiveStress in order
/// to check if cohesive elements have to be introduced
if (converged){
UInt new_cohesive_elements = checkCohesiveStress();
if(new_cohesive_elements == 0){
insertion_new_element = false;
} else {
insertion_new_element = true;
if (prank==0)
std::cout << "No. cohesive elements inserted = " << new_cohesive_elements << std::endl;
}
}
}
if (!converged && load_reduction)
insertion_new_element = false;
/// If convergence is not reached, there is the possibility to
/// return back to the main file and reduce the load. Before doing
/// this, a pre-fixed value as to be defined for the parameter
/// delta_max of the cohesive elements introduced in the current
/// incremental step. This is done by calling the function
/// checkDeltaMax.
if (!converged) {
insertion_new_element = false;
for (UInt m = 0; m < materials.size(); ++m) {
try {
MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(*materials[m]);
mat.checkDeltaMax(_not_ghost);
} catch(std::bad_cast&) { }
}
}
} //end loop for the insertion of new cohesive elements
/// When the solution to the current incremental step is computed
/// (no more cohesive elements have to be introduced), call the
/// function to compute the energies.
if ((is_extrinsic && converged)) {
for(UInt m = 0; m < materials.size(); ++m) {
try {
MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(*materials[m]);
mat.computeEnergies();
} catch (std::bad_cast & bce) { }
}
EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
/// The function resetVariables is necessary to correctly set a
/// variable that permit to decrease locally the penalty parameter
/// for compression.
for (UInt m = 0; m < materials.size(); ++m) {
try {
MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(*materials[m]);
mat.resetVariables(_not_ghost);
} catch(std::bad_cast&) { }
}
/// The correct solution is saved
this->displacement->copy(*displacement_tmp);
this->velocity ->copy(*velocity_tmp);
this->acceleration->copy(*acceleration_tmp);
delete displacement_tmp;
delete velocity_tmp;
delete acceleration_tmp;
}
return insertion_new_element;
}
__END_AKANTU__
#if defined (AKANTU_PARALLEL_COHESIVE_ELEMENT)
# include "solid_mechanics_model_cohesive_parallel_inline_impl.cc"
#endif
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_element.hh b/src/model/solid_mechanics/solid_mechanics_model_element.hh
index 7c7d22ff9..a5facf322 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_element.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_element.hh
@@ -1,547 +1,547 @@
/**
* @file solid_mechanics_model_element.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue May 07 2013
- * @date last modification: Tue May 13 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief elements for solid mechanics models
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_SOLID_MECHANICS_MODEL_ELEMENT_HH
#define AKANTU_SOLID_MECHANICS_MODEL_ELEMENT_HH
#include <array/expr.hpp>
#include "mesh.hh"
#include "aka_error.hh"
#include "solid_mechanics_model.hh"
#include "aka_bounding_box.hh"
__BEGIN_AKANTU__
typedef array::vector_type<Real> vector_type;
typedef array::matrix_type<Real> matrix_type;
template <>
class ModelElement<SolidMechanicsModel> : public Element {
public:
typedef Element element_base;
SolidMechanicsModel *model_; //!< Reference to model
UInt *connectivity_; //!< Ponter to connectivity array
typedef SolidMechanicsModel model_type;
ModelElement() : element_base(), model_(nullptr), connectivity_() {}
ModelElement(SolidMechanicsModel& m, Element &el)
: element_base(el), model_(&m) {
connectivity_ = &m.getMesh().getConnectivity(this->type, this->ghost_type)(this->element);
}
ModelElement(SolidMechanicsModel& m, ElementType type, UInt id, GhostType gt = _not_ghost)
: element_base(type, id, gt), model_(&m) {
connectivity_ = &m.getMesh().getConnectivity(type, gt)(id);
}
ModelElement(const ModelElement& p) : element_base(static_cast<element_base>(p)), model_(p.model_), connectivity_(p.connectivity_) {}
model_type& model() { return *model_; }
UInt numNodes() const
{ return Mesh::getNbNodesPerElement(type); }
template <class element_type>
bool shareNodes(element_type& el) {
for (UInt i=0; i<Mesh::getNbNodesPerElement(type); ++i)
for (UInt j=0; j<Mesh::getNbNodesPerElement(el.type); ++j)
if (connectivity_[i] == el.connectivity_[j])
return true;
return false;
}
template <class element_type>
UInt shareNode(element_type& el) {
for (UInt i=0; i<Mesh::getNbNodesPerElement(type); ++i)
for (UInt j=0; j<Mesh::getNbNodesPerElement(el.type); ++j)
if (connectivity_[i] == el.connectivity_[j])
return connectivity_[i];
return -1;
}
UInt& node(UInt n) {
AKANTU_DEBUG_ASSERT(n < Mesh::getNbNodesPerElement(type),
"Node "<<n<<" is larger than element number of nodes: "<<Mesh::getNbNodesPerElement(type));
return connectivity_[n];
}
UInt node(UInt n) const {
AKANTU_DEBUG_ASSERT(n < Mesh::getNbNodesPerElement(type),
"Node "<<n<<" is larger than element number of nodes: "<<Mesh::getNbNodesPerElement(type));
return connectivity_[n];
}
// vector of pointers to nodes' first coordinates
std::vector<const Real*> coordinates() {
UInt nb_nodes = Mesh::getNbNodesPerElement(this->type);
const Array<Real> &position = model_->getCurrentPosition();
std::vector<const Real*> coord(nb_nodes);
for (size_t i=0; i<nb_nodes; ++i)
coord[i] = &position(connectivity_[i]);
return coord;
}
// barycenter
vector_type barycenter() const {
typedef typename vector_type::value_type value_type;
UInt nb_nodes = Mesh::getNbNodesPerElement(this->type);
const Array<Real> &position = model_->getCurrentPosition();
vector_type sum(model_->getSpatialDimension());
for (size_t i=0; i<nb_nodes; ++i) {
Real * p = const_cast<Real*>(&position(connectivity_[i]));
sum += vector_type(model_->getSpatialDimension(), p);
}
return (1./static_cast<value_type>(nb_nodes)) * sum;
}
//! Returns the closest point to an element and the element normal
vector_type normal() {
vector_type n;
auto coord = coordinates();
switch (type) {
case _segment_2:
{
// create points from segment
Point<2> x(coord[0]);
Point<2> y(coord[1]);
Point<2> t = y-x;
n = vector_type(2);
// normal2 normalizes the normal so that its magnitude is 1
Math::normal2(&t[0], &n[0]);
break;
}
case _triangle_3:
{
Point<3> x(coord[0]);
Point<3> y(coord[1]);
Point<3> z(coord[2]);
Point<3> t1 = y-x;
Point<3> t2 = z-x;
n = vector_type(3);
Math::vectorProduct3(&t1[0], &t2[0], &n[0]);
Math::normalize3(&n[0]);
break;
}
default:
AKANTU_DEBUG_ERROR("No element type found");
}
return n;
}
template <int dim>
BoundingBox<dim> boundingBox() {
typedef typename BoundingBox<dim>::point_type point_type;
assert(dim == model_->getSpatialDimension());
BoundingBox<dim> bb;
UInt nb_nodes = Mesh::getNbNodesPerElement(this->type);
const Array<Real> &position = model_->getCurrentPosition();
for (size_t i=0; i<nb_nodes; ++i) {
point_type p(&position(connectivity_[i]));
bb += p;
}
return bb;
}
template <int dim>
Point<dim> point(UInt nid) {
AKANTU_DEBUG_ASSERT(dim == model_->getSpatialDimension(),
"Point and model dimensions do not match");
UInt n = node(nid);
const Array<Real> &position = model_->getCurrentPosition();
Real * p = const_cast<Real*>(&position(n));
return Point<dim>(p);
}
// mass
vector_type getMass(UInt nid) {
UInt n = node(nid);
Array<Real> &mass = model_->getMass();
return vector_type(model_->getSpatialDimension(), &mass(n));
}
// mass for const objects
const vector_type getMass(UInt nid) const {
UInt n = node(nid);
Array<Real> &mass = model_->getMass();
return vector_type(model_->getSpatialDimension(), &mass(n));
}
// initial coordinates
vector_type getInitialCoordinates(UInt nid) {
UInt n = node(nid);
Array<Real> &coord = model_->getMesh().getNodes();
return vector_type(model_->getSpatialDimension(), &coord(n));
}
const vector_type getInitialCoordinates(UInt nid) const {
UInt n = node(nid);
Array<Real> &coord = model_->getMesh().getNodes();
return vector_type(model_->getSpatialDimension(), &coord(n));
}
// displacement
vector_type getDisplacement(UInt nid) {
UInt n = node(nid);
Array<Real> &displacement = model_->getDisplacement();
return vector_type(model_->getSpatialDimension(), &displacement(n));
}
// displacement for const objects
const vector_type getDisplacement(UInt nid) const {
UInt n = node(nid);
Array<Real> &displacement = model_->getDisplacement();
return vector_type(model_->getSpatialDimension(), &displacement(n));
}
// velocity
vector_type getVelocity(UInt nid) {
UInt n = node(nid);
Array<Real> &velocity = model_->getVelocity();
return vector_type(model_->getSpatialDimension(), &velocity(n));
}
// velocity for const objects
const vector_type getVelocity(UInt nid) const {
UInt n = node(nid);
Array<Real> &velocity = model_->getVelocity();
return vector_type(model_->getSpatialDimension(), &velocity(n));
}
// acceleration
vector_type getAcceleration(UInt nid) {
UInt n = node(nid);
Array<Real> &acceleration = model_->getAcceleration();
return vector_type(model_->getSpatialDimension(), &acceleration(n));
}
// acceleration for const objects
const vector_type getAcceleration(UInt nid) const {
UInt n = node(nid);
Array<Real> &acceleration = model_->getAcceleration();
return vector_type(model_->getSpatialDimension(), &acceleration(n));
}
// position (location + displacement)
vector_type getCurrentPosition(UInt nid) {
UInt n = node(nid);
const Array<Real> &position = model_->getCurrentPosition();
Real * p = const_cast<Real*>(&position(n));
return vector_type(model_->getSpatialDimension(), p);
}
// position (location + displacement) for const objects
const vector_type getCurrentPosition(UInt nid) const {
UInt n = node(nid);
const Array<Real> &position = model_->getCurrentPosition();
Real * p = const_cast<Real*>(&position(n));
return vector_type(model_->getSpatialDimension(), p);
}
// residual
vector_type getResidual(UInt nid) {
UInt n = node(nid);
const Array<Real> & residual = model_->getResidual();
Real * p = const_cast<Real*>(&residual(n));
return vector_type(model_->getSpatialDimension(), p);
}
// residual for const objects
const vector_type getResidual(UInt nid) const {
UInt n = node(nid);
const Array<Real> & residual = model_->getResidual();
Real * p = const_cast<Real*>(&residual(n));
return vector_type(model_->getSpatialDimension(), p);
}
// momentum
vector_type getMomentum(UInt nid) {
UInt n = node(nid);
Array<Real> &velocity = model_->getVelocity();
Array<Real> &mass = model_->getMass();
vector_type p(model_->getSpatialDimension());
for (size_t i=0; i<p.size(); ++i)
p[i] = mass(n,i)*velocity(n,i);
return p;
}
// momentum for const objects
const vector_type getMomentum(UInt nid) const {
return const_cast<ModelElement&>(*this).getMomentum(nid);
}
};
//! Returns the closest point to an element and the element normal
template <class point_type, class element_type>
std::pair<point_type, vector_type> closest_point_to_element(const point_type& p, element_type& el) {
point_type r;
vector_type n;
switch (el.type) {
case _segment_2:
{
// create points from segment
auto coord = el.coordinates();
assert (coord.size() == 2);
point_type x(coord[0]);
point_type y(coord[1]);
r = closest_point_to_segment(p, x, y);
point_type t = y-x;
n = vector_type(2);
Math::normal2(&t[0], &n[0]);
break;
}
default:
AKANTU_DEBUG_ERROR("No element type found");
}
return std::make_pair(r, n);
}
template <class point_type, class pair_type>
bool balance(Real Dt, int id, const pair_type& r, ModelElement<SolidMechanicsModel>& sel, ModelElement<SolidMechanicsModel>& mel) {
// constexpr int dim = point_type::dim();
// treat first element as slave
auto coord = sel.coordinates();
// create point
point_type p(coord[id]);
// else find closest distance from p to contacting element c2
// std::pair<point_type, vector_type> r = closest_point_to_element(p, mel);
const point_type& q = r.first;
const vector_type& n = r.second;
// get distance from current position
Real delta = sqrt((q-p).sq_norm());
auto mass = sel.getMass(id)[0];
// compute force at slave node
vector_type N = 2 * delta * mass / pow(Dt,2.) * n;
// update residual and velocity for slave
vector_type sr = sel.getResidual(id);
vector_type m = sel.getMass(id);
vector_type v = sel.getVelocity(id);
vector_type a = sel.getAcceleration(id);
for (size_t i=0; i<N.size(); ++i) {
// sr[i] = N[i];
v[i] += N[i]/m[i] * Dt;
// a[i] -= N[i]/m[i];
}
// set location of slave node
auto xs = sel.getDisplacement(id);
auto oc = sel.getInitialCoordinates(id);
for (size_t i=0; i<xs.size(); ++i)
xs[i] = q[i] - oc[i];
// balance with slave forces
switch (mel.type) {
case _segment_2:
{
// create points from segment
auto coord = mel.coordinates();
assert (coord.size() == 2);
point_type X1(coord[0]);
point_type X2(coord[1]);
// get weights for distribution of loads
Real alpha = (q - X1).sq_norm() / (X2 - X1).sq_norm();
//get vectors
vector_type R1 = mel.getResidual(0);
vector_type R2 = mel.getResidual(1);
vector_type V1 = mel.getVelocity(0);
vector_type V2 = mel.getVelocity(1);
// vector_type A1 = mel.getAcceleration(0);
// vector_type A2 = mel.getAcceleration(1);
vector_type M1 = mel.getMass(0);
vector_type M2 = mel.getMass(1);
for (size_t i=0; i<N.size(); ++i) {
Real r1 = (alpha - 1)*N[i];
Real r2 = -alpha * N[i];
// R1[i] = r1;
// R2[i] = r2;
V1[i] += r1/M1[i] * Dt;
V2[i] += r2/M2[i] * Dt;
// A1[i] -= R1[i]/M1[i];
// A2[i] -= R2[i]/M2[i];
}
break;
}
default:
AKANTU_DEBUG_ERROR("No element type found");
}
return true;
}
template <class point_type, class element_container>
std::pair<point_type, vector_type> commonPonit(const element_container& els) {
typedef std::pair<point_type, vector_type> pair_type;
// balance with slave forces
switch (els.size()) {
case 2:
{
auto it = els.begin();
auto el1 = *it++;
auto el2 = *it;
// get normals
auto n1 = el1.normal();
auto n2 = el2.normal();
// average normal
vector_type n = n1 + n2;
n *= (1/n.norm());
// get common point
assert(el1.shareNodes(el2));
UInt c = el1.shareNode(el2);
assert(el1.shareNode(el2) == el2.shareNode(el1));
// set location of slave node
Array<Real> &displacement = el1.model().getDisplacement();
Array<Real> &coord = el1.model().getMesh().getNodes();
point_type p;
for (int i=0; i<point_type::dim(); ++i)
p[i] = coord(c,i) + displacement(c,i);
return std::make_pair(p,n);
break;
}
default:
AKANTU_DEBUG_ERROR("Invalid size");
}
return pair_type();
}
template <class point_type, class element_type>
bool penetrates(point_type& r, element_type& el) {
// balance with slave forces
switch (el.type) {
case _segment_2:
{
// create points from master
auto coord = el.coordinates();
assert (coord.size() == 2);
point_type p(coord[0]);
point_type q(coord[1]);
return left_turn(p,q,r) > 0 && has_projection(r, p, q);
break;
}
default:
AKANTU_DEBUG_ERROR("No element type found");
}
// should never get here
assert(false);
return false;
}
__END_AKANTU__
#endif /* AKANTU_SOLID_MECHANICS_MODEL_ELEMENT_HH */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
index c8b7fc796..85934400d 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
@@ -1,160 +1,160 @@
/**
- * @file embedded_interface_intersector.cc
+ * @file embedded_interface_intersector.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Wed Apr 29 2015
- * @date last modification: Wed Apr 29 2015
+ * @date creation: Fri May 01 2015
+ * @date last modification: Mon Jan 04 2016
*
- * @brief Class that loads the interface from mesh and computes intersections
+ * @brief Class that loads the interface from mesh and computes intersections
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "embedded_interface_intersector.hh"
#include "mesh_segment_intersector.hh"
/// Helper macro for types in the mesh. Creates an intersector and computes intersection queries
#define INTERFACE_INTERSECTOR_CASE(dim, type) do { \
MeshSegmentIntersector<dim, type> intersector(this->mesh, interface_mesh); \
name_to_primitives_it = name_to_primitives_map.begin(); \
for (; name_to_primitives_it != name_to_primitives_end ; ++name_to_primitives_it) { \
intersector.setPhysicalName(name_to_primitives_it->first); \
intersector.buildResultFromQueryList(name_to_primitives_it->second); \
} } while(0)
#define INTERFACE_INTERSECTOR_CASE_2D(type) INTERFACE_INTERSECTOR_CASE(2, type)
#define INTERFACE_INTERSECTOR_CASE_3D(type) INTERFACE_INTERSECTOR_CASE(3, type)
__BEGIN_AKANTU__
EmbeddedInterfaceIntersector::EmbeddedInterfaceIntersector(Mesh & mesh, const Mesh & primitive_mesh) :
MeshGeomAbstract(mesh),
interface_mesh(mesh.getSpatialDimension(), "interface_mesh"),
primitive_mesh(primitive_mesh)
{
// Initiating mesh connectivity and data
interface_mesh.addConnectivityType(_segment_2, _not_ghost);
interface_mesh.addConnectivityType(_segment_2, _ghost);
interface_mesh.registerData<Element>("associated_element").alloc(0, 1, _segment_2);
interface_mesh.registerData<std::string>("physical_names").alloc(0, 1, _segment_2);
}
EmbeddedInterfaceIntersector::~EmbeddedInterfaceIntersector()
{}
void EmbeddedInterfaceIntersector::constructData(GhostType ghost_type) {
AKANTU_DEBUG_IN();
const UInt dim = this->mesh.getSpatialDimension();
if (dim == 1)
AKANTU_DEBUG_ERROR("No embedded model in 1D. Deactivate intersection initialization");
Array<std::string> * physical_names = NULL;
try {
physical_names = &const_cast<Array<std::string> &>(this->primitive_mesh.getData<std::string>("physical_names", _segment_2));
} catch (debug::Exception & e) {
AKANTU_DEBUG_ERROR("You must define physical names to reinforcements in order to use the embedded model");
throw e;
}
const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_segment_2);
Array<UInt>::const_vector_iterator connectivity = primitive_mesh.getConnectivity(_segment_2).begin(nb_nodes_per_element);
Array<std::string>::scalar_iterator
names_it = physical_names->begin(),
names_end = physical_names->end();
std::map<std::string, std::list<K::Segment_3> > name_to_primitives_map;
// Loop over the physical names and register segment lists in name_to_primitives_map
for (; names_it != names_end ; ++names_it) {
UInt element_id = names_it - physical_names->begin();
const Vector<UInt> el_connectivity = connectivity[element_id];
K::Segment_3 segment = this->createSegment(el_connectivity);
name_to_primitives_map[*names_it].push_back(segment);
}
// Loop over the background types of the mesh
Mesh::type_iterator
type_it = this->mesh.firstType(dim, _not_ghost),
type_end = this->mesh.lastType(dim, _not_ghost);
std::map<std::string, std::list<K::Segment_3> >::iterator
name_to_primitives_it,
name_to_primitives_end = name_to_primitives_map.end();
for (; type_it != type_end ; ++type_it) {
// Used in AKANTU_BOOST_ELEMENT_SWITCH
ElementType type = *type_it;
AKANTU_DEBUG_INFO("Computing intersections with background element type " << type);
switch(dim) {
case 1:
break;
case 2:
// Compute intersections for supported 2D elements
AKANTU_BOOST_ELEMENT_SWITCH(INTERFACE_INTERSECTOR_CASE_2D, (_triangle_3) (_triangle_6));
break;
case 3:
// Compute intersections for supported 3D elements
AKANTU_BOOST_ELEMENT_SWITCH(INTERFACE_INTERSECTOR_CASE_3D, (_tetrahedron_4));
break;
}
}
AKANTU_DEBUG_OUT();
}
K::Segment_3 EmbeddedInterfaceIntersector::createSegment(const Vector<UInt> & connectivity) {
AKANTU_DEBUG_IN();
K::Point_3 * source = NULL, * target = NULL;
const Array<Real> & nodes = this->primitive_mesh.getNodes();
if (this->mesh.getSpatialDimension() == 2) {
source = new K::Point_3(nodes(connectivity(0), 0), nodes(connectivity(0), 1), 0.);
target = new K::Point_3(nodes(connectivity(1), 0), nodes(connectivity(1), 1), 0.);
} else if (this->mesh.getSpatialDimension() == 3) {
source = new K::Point_3(nodes(connectivity(0), 0), nodes(connectivity(0), 1), nodes(connectivity(0), 2));
target = new K::Point_3(nodes(connectivity(1), 0), nodes(connectivity(1), 1), nodes(connectivity(1), 2));
}
K::Segment_3 segment(*source, *target);
delete source;
delete target;
AKANTU_DEBUG_OUT();
return segment;
}
__END_AKANTU__
#undef INTERFACE_INTERSECTOR_CASE
#undef INTERFACE_INTERSECTOR_CASE_2D
#undef INTERFACE_INTERSECTOR_CASE_3D
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
index e5be8b93d..d36d382d3 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
@@ -1,91 +1,91 @@
/**
- * @file embedded_interface_intersector.hh
+ * @file embedded_interface_intersector.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Wed Apr 29 2015
- * @date last modification: Wed Apr 29 2015
+ * @date creation: Fri May 01 2015
+ * @date last modification: Mon Dec 14 2015
*
- * @brief Class that loads the interface from mesh and computes intersections
+ * @brief Class that loads the interface from mesh and computes intersections
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_EMBEDDED_INTERFACE_INTERSECTOR_HH__
#define __AKANTU_EMBEDDED_INTERFACE_INTERSECTOR_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
#include "mesh_geom_abstract.hh"
#include "mesh_segment_intersector.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
typedef Cartesian K;
/**
* @brief Computes the intersections of the reinforcements defined in the primitive mesh
*
* The purpose of this class is to look for reinforcements in the primitive mesh, which
* should be defined by physical groups with the same names as the reinforcement materials
* in the model.
*
* It then constructs the CGAL primitives from the elements of those reinforcements
* and computes the intersections with the background mesh, to create an `interface_mesh`,
* which is in turn used by the EmbeddedInterfaceModel.
*
* @see MeshSegmentIntersector, MeshGeomAbstract
* @see EmbeddedInterfaceModel
*/
class EmbeddedInterfaceIntersector : public MeshGeomAbstract {
public:
/// Construct from mesh and a reinforcement mesh
explicit EmbeddedInterfaceIntersector(Mesh & mesh, const Mesh & primitive_mesh);
/// Destructor
virtual ~EmbeddedInterfaceIntersector();
public:
/// Generate the interface mesh
virtual void constructData(GhostType ghost_type = _not_ghost);
/// Create a segment with an element connectivity
K::Segment_3 createSegment(const Vector<UInt> & connectivity);
/// Getter for interface mesh
AKANTU_GET_MACRO_NOT_CONST(InterfaceMesh, interface_mesh, Mesh &);
protected:
/// Resulting mesh of intersection
Mesh interface_mesh;
/// Mesh used for primitive construction
const Mesh & primitive_mesh;
};
__END_AKANTU__
#endif // __AKANTU_EMBEDDED_INTERFACE_INTERSECTOR_HH__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
index cf922d8ab..30d1db3f3 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
@@ -1,210 +1,210 @@
/**
* @file embedded_interface_model.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Mon Mar 9 2015
- * @date last modification: Mon Mar 9 2015
+ * @date creation: Fri Mar 13 2015
+ * @date last modification: Mon Dec 14 2015
*
* @brief Model of Solid Mechanics with embedded interfaces
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "embedded_interface_model.hh"
#include "material_reinforcement.hh"
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
# include "dumpable_inline_impl.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const EmbeddedInterfaceModelOptions
default_embedded_interface_model_options(_explicit_lumped_mass, false, false);
/* -------------------------------------------------------------------------- */
EmbeddedInterfaceModel::EmbeddedInterfaceModel(Mesh & mesh,
Mesh & primitive_mesh,
UInt spatial_dimension,
const ID & id,
const MemoryID & memory_id) :
SolidMechanicsModel(mesh, spatial_dimension, id, memory_id),
intersector(mesh, primitive_mesh),
interface_mesh(NULL),
primitive_mesh(primitive_mesh),
interface_material_selector(NULL)
{
// This pointer should be deleted by ~SolidMechanicsModel()
MaterialSelector * mat_sel_pointer =
new MeshDataMaterialSelector<std::string>("physical_names", *this);
this->setMaterialSelector(*mat_sel_pointer);
interface_mesh = &(intersector.getInterfaceMesh());
// Create 1D FEEngine on the interface mesh
registerFEEngineObject<MyFEEngineType>("EmbeddedInterfaceFEEngine", *interface_mesh, 1);
}
/* -------------------------------------------------------------------------- */
EmbeddedInterfaceModel::~EmbeddedInterfaceModel() {
delete interface_material_selector;
}
/* -------------------------------------------------------------------------- */
void EmbeddedInterfaceModel::initFull(const ModelOptions & options) {
const EmbeddedInterfaceModelOptions & eim_options =
dynamic_cast<const EmbeddedInterfaceModelOptions &>(options);
// We don't want to initiate materials before shape functions are initialized
SolidMechanicsModelOptions dummy_options(eim_options.analysis_method, true);
// Do no initialize interface_mesh if told so
if (!eim_options.no_init_intersections)
intersector.constructData();
// Initialize interface FEEngine
FEEngine & engine = getFEEngine("EmbeddedInterfaceFEEngine");
engine.initShapeFunctions(_not_ghost);
engine.initShapeFunctions(_ghost);
SolidMechanicsModel::initFull(dummy_options);
// This will call SolidMechanicsModel::initMaterials() last
this->initMaterials();
#if defined(AKANTU_USE_IOHELPER)
this->mesh.registerDumper<DumperParaview>("reinforcement", id);
this->mesh.addDumpMeshToDumper("reinforcement", *interface_mesh,
1, _not_ghost, _ek_regular);
#endif
}
/* -------------------------------------------------------------------------- */
// This function is very similar to SolidMechanicsModel's
void EmbeddedInterfaceModel::initMaterials() {
Element element;
delete interface_material_selector;
interface_material_selector =
new InterfaceMeshDataMaterialSelector<std::string>("physical_names", *this);
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
element.ghost_type = *gt;
Mesh::type_iterator it = interface_mesh->firstType(1, *gt);
Mesh::type_iterator end = interface_mesh->lastType(1, *gt);
for (; it != end ; ++it) {
UInt nb_element = interface_mesh->getNbElement(*it, *gt);
element.type = *it;
Array<UInt> & mat_indexes = material_index.alloc(nb_element, 1, *it, *gt);
for (UInt el = 0 ; el < nb_element ; el++) {
element.element = el;
UInt mat_index = (*interface_material_selector)(element);
AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
"The material selector returned an index that does not exist");
mat_indexes(element.element) = mat_index;
materials.at(mat_index)->addElement(*it, el, *gt);
}
}
}
SolidMechanicsModel::initMaterials();
}
// /**
// * DO NOT REMOVE - This prevents the material reinforcement to register
// * their number of components. Problems arise with AvgHomogenizingFunctor
// * if the material reinforcement gives its number of components for a
// * field. Since AvgHomogenizingFunctor verifies that all the fields
// * have the same number of components, an exception is raised.
// */
// ElementTypeMap<UInt> EmbeddedInterfaceModel::getInternalDataPerElem(const std::string & field_name,
// const ElementKind & kind) {
// if (!(this->isInternal(field_name,kind))) AKANTU_EXCEPTION("unknown internal " << field_name);
// for (UInt m = 0; m < materials.size() ; ++m) {
// if (materials[m]->isInternal<Real>(field_name, kind)) {
// Material * mat = NULL;
// switch(this->spatial_dimension) {
// case 1:
// mat = dynamic_cast<MaterialReinforcement<1> *>(materials[m]);
// break;
// case 2:
// mat = dynamic_cast<MaterialReinforcement<2> *>(materials[m]);
// break;
// case 3:
// mat = dynamic_cast<MaterialReinforcement<3> *>(materials[m]);
// break;
// }
// if (mat == NULL && field_name != "stress_embedded")
// return materials[m]->getInternalDataPerElem<Real>(field_name,kind);
// else if (mat != NULL && field_name == "stress_embedded")
// return mat->getInternalDataPerElem<Real>(field_name, kind, "EmbeddedInterfaceFEEngine");
// }
// }
// return ElementTypeMap<UInt>();
// }
/* -------------------------------------------------------------------------- */
void EmbeddedInterfaceModel::addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag) {
#ifdef AKANTU_USE_IOHELPER
dumper::Field * field = NULL;
// If dumper is reinforcement, create a 1D elemental field
if (dumper_name == "reinforcement")
field = this->createElementalField(field_id, group_name, padding_flag, 1, element_kind);
else {
try {
SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name, field_id, group_name, element_kind, padding_flag);
} catch (...) {}
}
if (field) {
DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name,group_name);
Model::addDumpGroupFieldToDumper(field_id,field,dumper);
}
#endif
}
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
index 26c64b5c7..3960c2cf8 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
@@ -1,166 +1,167 @@
/**
* @file embedded_interface_model.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Mon Mar 9 2015
- * @date last modification: Mon Mar 9 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Mon Dec 14 2015
*
* @brief Model of Solid Mechanics with embedded interfaces
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_EMBEDDED_INTERFACE_MODEL_HH__
#define __AKANTU_EMBEDDED_INTERFACE_MODEL_HH__
#include "aka_common.hh"
#include "solid_mechanics_model.hh"
#include "mesh.hh"
#include "embedded_interface_intersector.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/// Options for the EmbeddedInterfaceModel
struct EmbeddedInterfaceModelOptions : SolidMechanicsModelOptions {
/**
* @brief Constructor for EmbeddedInterfaceModelOptions
* @param analysis_method see SolidMeechanicsModelOptions
* @param no_init_intersections ignores the embedded elements
* @param no_init_materials see SolidMeechanicsModelOptions
*/
EmbeddedInterfaceModelOptions(AnalysisMethod analysis_method = _explicit_lumped_mass,
bool no_init_intersections = false,
bool no_init_materials = false):
SolidMechanicsModelOptions(analysis_method, no_init_materials),
no_init_intersections(no_init_intersections)
{}
/// Ignore the reinforcements
bool no_init_intersections;
};
extern const EmbeddedInterfaceModelOptions default_embedded_interface_model_options;
/**
* @brief Solid mechanics model using the embedded model.
*
* This SolidMechanicsModel subclass implements the embedded model,
* a method used to represent 1D elements in a finite elements model
* (eg. reinforcements in concrete).
*
* In addition to the SolidMechanicsModel properties, this model has
* a mesh of the 1D elements embedded in the model, and an instance of the
* EmbeddedInterfaceIntersector class for the computation of the intersections of the
* 1D elements with the background (bulk) mesh.
*
* @see MaterialReinforcement
*/
class EmbeddedInterfaceModel : public SolidMechanicsModel {
/// Same type as SolidMechanicsModel
typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular> MyFEEngineType;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
/**
* @brief Constructor
*
* @param mesh main mesh (concrete)
* @param primitive_mesh mesh of the embedded reinforcement
*/
EmbeddedInterfaceModel(Mesh & mesh,
Mesh & primitive_mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "embedded_interface_model",
const MemoryID & memory_id = 0);
/// Destructor
virtual ~EmbeddedInterfaceModel();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// Initialise the model
virtual void initFull(const ModelOptions & options = default_embedded_interface_model_options);
/// Initialise the materials
virtual void initMaterials();
/// Allows filtering of dump fields which need to be dumpes on interface mesh
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag);
// virtual ElementTypeMap<UInt> getInternalDataPerElem(const std::string & field_name,
// const ElementKind & kind);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Get interface mesh
AKANTU_GET_MACRO(InterfaceMesh, *interface_mesh, Mesh &);
/// Get associated elements
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(InterfaceAssociatedElements,
interface_mesh->getData<Element>("associated_element"),
Element);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Intersector object to build the interface mesh
EmbeddedInterfaceIntersector intersector;
/// Interface mesh (weak reference)
Mesh * interface_mesh;
/// Mesh used to create the CGAL primitives for intersections
Mesh & primitive_mesh;
/// Material selector for interface
MaterialSelector * interface_material_selector;
};
/// Material selector based on mesh data for interface elements
template<typename T>
class InterfaceMeshDataMaterialSelector : public ElementDataMaterialSelector<T> {
public:
InterfaceMeshDataMaterialSelector(const std::string & name, const EmbeddedInterfaceModel & model, UInt first_index = 1) :
ElementDataMaterialSelector<T>(model.getInterfaceMesh().getData<T>(name), model, first_index)
{}
};
__END_AKANTU__
#endif // __AKANTU_EMBEDDED_INTERFACE_MODEL_HH__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh b/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
index b785db245..06d583dac 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
@@ -1,108 +1,110 @@
/**
* @file solid_mechanics_model_event_handler.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Mar 14 2014
- * @date last modification: Fri May 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Dec 18 2015
*
* @brief EventHandler implementation for SolidMechanicsEvents
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__
__BEGIN_AKANTU__
///akantu::SolidMechanicsModelEvent is the base event for model
namespace SolidMechanicsModelEvent {
struct BeforeSolveStepEvent {
BeforeSolveStepEvent(AnalysisMethod & method) : method(method) {}
AnalysisMethod method;
};
struct AfterSolveStepEvent {
AfterSolveStepEvent(AnalysisMethod & method) : method(method) {}
AnalysisMethod method;
};
struct BeforeDumpEvent { BeforeDumpEvent() {} };
struct BeginningOfDamageIterationEvent { BeginningOfDamageIterationEvent() {} };
struct AfterDamageEvent { AfterDamageEvent() {} };
}
/// akantu::SolidMechanicsModelEvent
class SolidMechanicsModelEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
virtual ~SolidMechanicsModelEventHandler() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
///Send what is before the solve step to the beginning of solve step through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::BeforeSolveStepEvent & event) {
onBeginningSolveStep(event.method);
}
///Send what is after the solve step to the end of solve step through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::AfterSolveStepEvent & event) {
onEndSolveStep(event.method);
}
///Send what is before dump to current dump through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::BeforeDumpEvent & event) {
onDump();
}
///Send what is at the beginning of damage iteration to Damage iteration through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::BeginningOfDamageIterationEvent & event) {
onDamageIteration();
}
///Send what is after damage for the damage update through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::AfterDamageEvent & event) {
onDamageUpdate();
}
template<class EventHandler>
friend class EventHandlerManager;
/* ------------------------------------------------------------------------ */
/* Interface */
/* ------------------------------------------------------------------------ */
public:
/// function to implement to react on akantu::BeforeSolveStepEvent
virtual void onBeginningSolveStep(__attribute__((unused)) const AnalysisMethod & method) {}
/// function to implement to react on akantu::AfterSolveStepEvent
virtual void onEndSolveStep(__attribute__((unused)) const AnalysisMethod & method) {}
/// function to implement to react on akantu::BeforeDumpEvent
virtual void onDump() {}
/// function to implement to react on akantu::BeginningOfDamageIterationEvent
virtual void onDamageIteration() {}
/// function to implement to react on akantu::AfterDamageEvent
virtual void onDamageUpdate() {}
};
__END_AKANTU__
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
index 2eaa07aa2..e72176500 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
@@ -1,657 +1,658 @@
/**
* @file solid_mechanics_model_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 04 2010
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Wed Nov 18 2015
*
* @brief Implementation of the inline functions of the SolidMechanicsModel class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline Material & SolidMechanicsModel::getMaterial(UInt mat_index) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
"The model " << id << " has no material no "<< mat_index);
AKANTU_DEBUG_OUT();
return *materials[mat_index];
}
/* -------------------------------------------------------------------------- */
inline const Material & SolidMechanicsModel::getMaterial(UInt mat_index) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
"The model " << id << " has no material no "<< mat_index);
AKANTU_DEBUG_OUT();
return *materials[mat_index];
}
/* -------------------------------------------------------------------------- */
inline Material & SolidMechanicsModel::getMaterial(const std::string & name) {
AKANTU_DEBUG_IN();
std::map<std::string, UInt>::const_iterator it = materials_names_to_id.find(name);
AKANTU_DEBUG_ASSERT(it != materials_names_to_id.end(),
"The model " << id << " has no material named "<< name);
AKANTU_DEBUG_OUT();
return *materials[it->second];
}
/* -------------------------------------------------------------------------- */
inline UInt SolidMechanicsModel::getMaterialIndex(const std::string & name) const {
AKANTU_DEBUG_IN();
std::map<std::string, UInt>::const_iterator it = materials_names_to_id.find(name);
AKANTU_DEBUG_ASSERT(it != materials_names_to_id.end(),
"The model " << id << " has no material named "<< name);
AKANTU_DEBUG_OUT();
return it->second;
}
/* -------------------------------------------------------------------------- */
inline const Material & SolidMechanicsModel::getMaterial(const std::string & name) const {
AKANTU_DEBUG_IN();
std::map<std::string, UInt>::const_iterator it = materials_names_to_id.find(name);
AKANTU_DEBUG_ASSERT(it != materials_names_to_id.end(),
"The model " << id << " has no material named "<< name);
AKANTU_DEBUG_OUT();
return *materials[it->second];
}
/* -------------------------------------------------------------------------- */
inline void SolidMechanicsModel::setMaterialSelector(MaterialSelector & selector) {
if(is_default_material_selector) delete material_selector;
material_selector = &selector;
is_default_material_selector = false;
}
/* -------------------------------------------------------------------------- */
inline FEEngine & SolidMechanicsModel::getFEEngineBoundary(const ID & name) {
return dynamic_cast<FEEngine &>(getFEEngineClassBoundary<MyFEEngineType>(name));
}
/* -------------------------------------------------------------------------- */
inline void SolidMechanicsModel::splitElementByMaterial(const Array<Element> & elements,
Array<Element> * elements_per_mat) const {
ElementType current_element_type = _not_defined;
GhostType current_ghost_type = _casper;
const Array<UInt> * mat_indexes = NULL;
const Array<UInt> * mat_loc_num = NULL;
Array<Element>::const_iterator<Element> it = elements.begin();
Array<Element>::const_iterator<Element> end = elements.end();
for (; it != end; ++it) {
Element el = *it;
if(el.type != current_element_type || el.ghost_type != current_ghost_type) {
current_element_type = el.type;
current_ghost_type = el.ghost_type;
mat_indexes = &(this->material_index(el.type, el.ghost_type));
mat_loc_num = &(this->material_local_numbering(el.type, el.ghost_type));
}
UInt old_id = el.element;
el.element = (*mat_loc_num)(old_id);
elements_per_mat[(*mat_indexes)(old_id)].push_back(el);
}
}
/* -------------------------------------------------------------------------- */
inline UInt SolidMechanicsModel::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
UInt nb_nodes_per_element = 0;
Array<Element>::const_iterator<Element> it = elements.begin();
Array<Element>::const_iterator<Element> end = elements.end();
for (; it != end; ++it) {
const Element & el = *it;
nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
}
switch(tag) {
case _gst_material_id: {
size += elements.getSize() * sizeof(UInt);
break;
}
case _gst_smm_mass: {
size += nb_nodes_per_element * sizeof(Real) * spatial_dimension; // mass vector
break;
}
case _gst_smm_for_gradu: {
size += nb_nodes_per_element * spatial_dimension * sizeof(Real); // displacement
break;
}
case _gst_smm_boundary: {
// force, displacement, boundary
size += nb_nodes_per_element * spatial_dimension * (2 * sizeof(Real) + sizeof(bool));
break;
}
case _gst_for_dump: {
// displacement, velocity, acceleration, residual, force
size += nb_nodes_per_element * spatial_dimension * sizeof(Real) * 5;
break;
}
default: { }
}
if(tag != _gst_material_id) {
Array<Element> * elements_per_mat = new Array<Element>[materials.size()];
this->splitElementByMaterial(elements, elements_per_mat);
for (UInt i = 0; i < materials.size(); ++i) {
size += materials[i]->getNbDataForElements(elements_per_mat[i], tag);
}
delete [] elements_per_mat;
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void SolidMechanicsModel::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_material_id: {
packElementalDataHelper(material_index, buffer, elements, false, getFEEngine());
break;
}
case _gst_smm_mass: {
packNodalDataHelper(*mass, buffer, elements, mesh);
break;
}
case _gst_smm_for_gradu: {
packNodalDataHelper(*displacement, buffer, elements, mesh);
break;
}
case _gst_for_dump: {
packNodalDataHelper(*displacement, buffer, elements, mesh);
packNodalDataHelper(*velocity, buffer, elements, mesh);
packNodalDataHelper(*acceleration, buffer, elements, mesh);
packNodalDataHelper(*residual, buffer, elements, mesh);
packNodalDataHelper(*force, buffer, elements, mesh);
break;
}
case _gst_smm_boundary: {
packNodalDataHelper(*force, buffer, elements, mesh);
packNodalDataHelper(*velocity, buffer, elements, mesh);
packNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
break;
}
default: {
}
}
if(tag != _gst_material_id) {
Array<Element> * elements_per_mat = new Array<Element>[materials.size()];
splitElementByMaterial(elements, elements_per_mat);
for (UInt i = 0; i < materials.size(); ++i) {
materials[i]->packElementData(buffer, elements_per_mat[i], tag);
}
delete [] elements_per_mat;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void SolidMechanicsModel::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_material_id: {
unpackElementalDataHelper(material_index, buffer, elements,
false, getFEEngine());
break;
}
case _gst_smm_mass: {
unpackNodalDataHelper(*mass, buffer, elements, mesh);
break;
}
case _gst_smm_for_gradu: {
unpackNodalDataHelper(*displacement, buffer, elements, mesh);
break;
}
case _gst_for_dump: {
unpackNodalDataHelper(*displacement, buffer, elements, mesh);
unpackNodalDataHelper(*velocity, buffer, elements, mesh);
unpackNodalDataHelper(*acceleration, buffer, elements, mesh);
unpackNodalDataHelper(*residual, buffer, elements, mesh);
unpackNodalDataHelper(*force, buffer, elements, mesh);
break;
}
case _gst_smm_boundary: {
unpackNodalDataHelper(*force, buffer, elements, mesh);
unpackNodalDataHelper(*velocity, buffer, elements, mesh);
unpackNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
break;
}
default: {
}
}
if(tag != _gst_material_id) {
Array<Element> * elements_per_mat = new Array<Element>[materials.size()];
splitElementByMaterial(elements, elements_per_mat);
for (UInt i = 0; i < materials.size(); ++i) {
materials[i]->unpackElementData(buffer, elements_per_mat[i], tag);
}
delete [] elements_per_mat;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline UInt SolidMechanicsModel::getNbDataToPack(SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
// UInt nb_nodes = mesh.getNbNodes();
switch(tag) {
case _gst_smm_uv: {
size += sizeof(Real) * spatial_dimension * 2;
break;
}
case _gst_smm_res: {
size += sizeof(Real) * spatial_dimension;
break;
}
case _gst_smm_mass: {
size += sizeof(Real) * spatial_dimension;
break;
}
case _gst_for_dump: {
size += sizeof(Real) * spatial_dimension * 5;
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline UInt SolidMechanicsModel::getNbDataToUnpack(SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
// UInt nb_nodes = mesh.getNbNodes();
switch(tag) {
case _gst_smm_uv: {
size += sizeof(Real) * spatial_dimension * 2;
break;
}
case _gst_smm_res: {
size += sizeof(Real) * spatial_dimension;
break;
}
case _gst_smm_mass: {
size += sizeof(Real) * spatial_dimension;
break;
}
case _gst_for_dump: {
size += sizeof(Real) * spatial_dimension * 5;
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void SolidMechanicsModel::packData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_smm_uv: {
Array<Real>::const_vector_iterator it_disp = displacement->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_velo = velocity->begin(spatial_dimension);
Vector<Real> disp(it_disp[index]); buffer << disp;
Vector<Real> velo(it_velo[index]); buffer << velo;
break;
}
case _gst_smm_res: {
Array<Real>::const_vector_iterator it_res = residual->begin(spatial_dimension);
Vector<Real> resi(it_res[index]); buffer << resi;
break;
}
case _gst_smm_mass: {
AKANTU_DEBUG_INFO("pack mass of node " << index << " which is " << (*mass)(index,0));
Array<Real>::const_vector_iterator it_mass = mass->begin(spatial_dimension);
Vector<Real> mass(it_mass[index]); buffer << mass;
break;
}
case _gst_for_dump: {
Array<Real>::const_vector_iterator it_disp = displacement->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_velo = velocity->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_acce = acceleration->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_resi = residual->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_forc = force->begin(spatial_dimension);
Vector<Real> disp(it_disp[index]); buffer << disp;
Vector<Real> velo(it_velo[index]); buffer << velo;
Vector<Real> acce(it_acce[index]); buffer << acce;
Vector<Real> resi(it_resi[index]); buffer << resi;
Vector<Real> forc(it_forc[index]); buffer << forc;
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void SolidMechanicsModel::unpackData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_smm_uv: {
Array<Real>::vector_iterator it_disp = displacement->begin(spatial_dimension);
Array<Real>::vector_iterator it_velo = velocity->begin(spatial_dimension);
Vector<Real> disp(it_disp[index]); buffer >> disp;
Vector<Real> velo(it_velo[index]); buffer >> velo;
break;
}
case _gst_smm_res: {
Array<Real>::vector_iterator it_res = residual->begin(spatial_dimension);
Vector<Real> res(it_res[index]); buffer >> res;
break;
}
case _gst_smm_mass: {
AKANTU_DEBUG_INFO("mass of node " << index << " was " << (*mass)(index,0));
Array<Real>::vector_iterator it_mass = mass->begin(spatial_dimension);
Vector<Real> mass_v(it_mass[index]); buffer >> mass_v;
AKANTU_DEBUG_INFO("mass of node " << index << " is now " << (*mass)(index,0));
break;
}
case _gst_for_dump: {
Array<Real>::vector_iterator it_disp = displacement->begin(spatial_dimension);
Array<Real>::vector_iterator it_velo = velocity->begin(spatial_dimension);
Array<Real>::vector_iterator it_acce = acceleration->begin(spatial_dimension);
Array<Real>::vector_iterator it_resi = residual->begin(spatial_dimension);
Array<Real>::vector_iterator it_forc = force->begin(spatial_dimension);
Vector<Real> disp(it_disp[index]); buffer >> disp;
Vector<Real> velo(it_velo[index]); buffer >> velo;
Vector<Real> acce(it_acce[index]); buffer >> acce;
Vector<Real> resi(it_resi[index]); buffer >> resi;
Vector<Real> forc(it_forc[index]); buffer >> forc;
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
#include "sparse_matrix.hh"
#include "solver.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <NewmarkBeta::IntegrationSchemeCorrectorType type>
void SolidMechanicsModel::solve(Array<Real> &increment, Real block_val,
bool need_factorize, bool has_profile_changed) {
if(has_profile_changed) {
this->initJacobianMatrix();
need_factorize = true;
}
updateResidualInternal(); //doesn't do anything for static
if(need_factorize) {
Real c = 0.,d = 0.,e = 0.;
if(method == _static) {
AKANTU_DEBUG_INFO("Solving K inc = r");
e = 1.;
} else {
AKANTU_DEBUG_INFO("Solving (c M + d C + e K) inc = r");
NewmarkBeta * nmb_int = dynamic_cast<NewmarkBeta *>(integrator);
c = nmb_int->getAccelerationCoefficient<type>(time_step);
d = nmb_int->getVelocityCoefficient<type>(time_step);
e = nmb_int->getDisplacementCoefficient<type>(time_step);
}
jacobian_matrix->clear();
// J = c M + d C + e K
if(stiffness_matrix)
jacobian_matrix->add(*stiffness_matrix, e);
if(mass_matrix)
jacobian_matrix->add(*mass_matrix, c);
#if !defined(AKANTU_NDEBUG)
if(mass_matrix && AKANTU_DEBUG_TEST(dblDump)) {
UInt prank = StaticCommunicator::getStaticCommunicator().whoAmI();
std::stringstream sstr; sstr << "M" << prank << ".mtx";
mass_matrix->saveMatrix(sstr.str());
}
#endif
if(velocity_damping_matrix)
jacobian_matrix->add(*velocity_damping_matrix, d);
jacobian_matrix->applyBoundary(*blocked_dofs, block_val);
#if !defined(AKANTU_NDEBUG)
if(AKANTU_DEBUG_TEST(dblDump)) {
UInt prank = StaticCommunicator::getStaticCommunicator().whoAmI();
std::stringstream sstr; sstr << "J" << prank << ".mtx";
jacobian_matrix->saveMatrix(sstr.str());
}
#endif
solver->factorize();
}
// if (rhs.getSize() != 0)
// solver->setRHS(rhs);
// else
solver->setOperators();
solver->setRHS(*residual);
// solve @f[ J \delta w = r @f]
solver->solve(increment);
UInt nb_nodes = displacement-> getSize();
UInt nb_degree_of_freedom = displacement->getNbComponent() * nb_nodes;
bool * blocked_dofs_val = blocked_dofs->storage();
Real * increment_val = increment.storage();
for (UInt j = 0; j < nb_degree_of_freedom;
++j,++increment_val, ++blocked_dofs_val) {
if ((*blocked_dofs_val))
*increment_val = 0.0;
}
}
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool SolidMechanicsModel::solveStatic(Real tolerance, UInt max_iteration,
bool do_not_factorize) {
AKANTU_DEBUG_INFO("Solving Ku = f");
AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
"You should first initialize the implicit solver and assemble the stiffness matrix by calling initImplicit");
AnalysisMethod analysis_method=method;
Real error = 0.;
method=_static;
bool converged = this->template solveStep<cmethod, criteria>(tolerance, error, max_iteration, do_not_factorize);
method=analysis_method;
return converged;
}
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool SolidMechanicsModel::solveStep(Real tolerance,
UInt max_iteration) {
Real error = 0.;
return this->template solveStep<cmethod,criteria>(tolerance,
error,
max_iteration);
}
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool SolidMechanicsModel::solveStep(Real tolerance, Real & error, UInt max_iteration,
bool do_not_factorize) {
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
this->implicitPred();
this->updateResidual();
AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
"You should first initialize the implicit solver and assemble the stiffness matrix");
bool need_factorize = !do_not_factorize;
if (method==_implicit_dynamic) {
AKANTU_DEBUG_ASSERT(mass_matrix != NULL,
"You should first initialize the implicit solver and assemble the mass matrix");
}
switch (cmethod) {
case _scm_newton_raphson_tangent:
case _scm_newton_raphson_tangent_not_computed:
break;
case _scm_newton_raphson_tangent_modified:
this->assembleStiffnessMatrix();
break;
default:
AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
}
this->n_iter = 0;
bool converged = false;
error = 0.;
if(criteria == _scc_residual) {
converged = this->testConvergence<criteria> (tolerance, error);
if (converged) {
EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
if(increment_flag && previous_displacement) {
this->updateIncrement();
}
if(previous_displacement) previous_displacement->copy(*displacement);
return converged;
}
}
do {
if (cmethod == _scm_newton_raphson_tangent)
this->assembleStiffnessMatrix();
solve<NewmarkBeta::_displacement_corrector> (*increment, 1., need_factorize);
this->implicitCorr();
if(criteria == _scc_residual) this->updateResidual();
converged = this->testConvergence<criteria> (tolerance, error);
if(criteria == _scc_increment && !converged) this->updateResidual();
//this->dump();
this->n_iter++;
AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration "
<< std::setw(std::log10(max_iteration)) << this->n_iter
<< ": error " << error << (converged ? " < " : " > ") << tolerance);
switch (cmethod) {
case _scm_newton_raphson_tangent:
need_factorize = true;
break;
case _scm_newton_raphson_tangent_not_computed:
case _scm_newton_raphson_tangent_modified:
need_factorize = false;
break;
default:
AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
}
} while (!converged && this->n_iter < max_iteration);
// this makes sure that you have correct strains and stresses after the solveStep function (e.g., for dumping)
if(criteria == _scc_increment) this->updateResidual();
if (converged) {
EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
if(increment_flag && previous_displacement) {
this->updateIncrement();
}
if(previous_displacement) previous_displacement->copy(*displacement);
} else if(this->n_iter == max_iteration) {
AKANTU_DEBUG_WARNING("[" << criteria << "] Convergence not reached after "
<< std::setw(std::log10(max_iteration)) << this->n_iter <<
" iteration" << (this->n_iter == 1 ? "" : "s") << "!" << std::endl);
}
return converged;
}
diff --git a/src/model/solid_mechanics/solid_mechanics_model_mass.cc b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
index 6f186e85e..12c948082 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_mass.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
@@ -1,158 +1,159 @@
/**
* @file solid_mechanics_model_mass.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Oct 05 2010
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Fri Oct 16 2015
*
* @brief function handling mass computation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "solid_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMassLumped() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
if (!mass) {
std::stringstream sstr_mass; sstr_mass << id << ":mass";
mass = &(alloc<Real>(sstr_mass.str(), nb_nodes, spatial_dimension, 0));
} else
mass->clear();
assembleMassLumped(_not_ghost);
assembleMassLumped(_ghost);
/// for not connected nodes put mass to one in order to avoid
/// wrong range in paraview
Real * mass_values = mass->storage();
for (UInt i = 0; i < nb_nodes; ++i) {
if (fabs(mass_values[i]) < std::numeric_limits<Real>::epsilon() || Math::isnan(mass_values[i]))
mass_values[i] = 1.;
}
synch_registry->synchronize(_gst_smm_mass);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMassLumped(GhostType ghost_type) {
AKANTU_DEBUG_IN();
FEEngine & fem = getFEEngine();
Array<Real> rho_1(0,1);
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
computeRho(rho_1, type, ghost_type);
AKANTU_DEBUG_ASSERT(dof_synchronizer,
"DOFSynchronizer number must not be initialized");
fem.assembleFieldLumped(rho_1, spatial_dimension,*mass,
dof_synchronizer->getLocalDOFEquationNumbers(),
type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMass() {
AKANTU_DEBUG_IN();
if(!mass_matrix) {
std::stringstream sstr; sstr << id << ":mass_matrix";
mass_matrix = new SparseMatrix(*jacobian_matrix, sstr.str(), memory_id);
}
assembleMass(_not_ghost);
// assembleMass(_ghost);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMass(GhostType ghost_type) {
AKANTU_DEBUG_IN();
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
Array<Real> rho_1(0,1);
//UInt nb_element;
mass_matrix->clear();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
computeRho(rho_1, type, ghost_type);
fem.assembleFieldMatrix(rho_1, spatial_dimension, *mass_matrix, type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::computeRho(Array<Real> & rho,
ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Material ** mat_val = &(this->materials.at(0));
FEEngine & fem = this->getFEEngine();
UInt nb_element = fem.getMesh().getNbElement(type,ghost_type);
Array<UInt> & mat_indexes = this->material_index(type, ghost_type);
UInt nb_quadrature_points = fem.getNbIntegrationPoints(type);
rho.resize(nb_element * nb_quadrature_points);
Real * rho_1_val = rho.storage();
/// compute @f$ rho @f$ for each nodes of each element
for (UInt el = 0; el < nb_element; ++el) {
Real mat_rho = mat_val[mat_indexes(el)]->getParam<Real>("rho"); /// here rho is constant in an element
for (UInt n = 0; n < nb_quadrature_points; ++n) {
*rho_1_val++ = mat_rho;
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_material.cc b/src/model/solid_mechanics/solid_mechanics_model_material.cc
index 115c293c1..3fdaa3c41 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_material.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_material.cc
@@ -1,330 +1,331 @@
/**
* @file solid_mechanics_model_material.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Nov 26 2010
- * @date last modification: Tue Jun 24 2014
+ * @date last modification: Mon Nov 16 2015
*
* @brief instatiation of materials
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "solid_mechanics_model.hh"
#include "material_list.hh"
#include "aka_math.hh"
#ifdef AKANTU_DAMAGE_NON_LOCAL
# include "non_local_manager.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
#define AKANTU_INTANTIATE_MATERIAL_BY_DIM_NO_TMPL(dim, elem) \
registerNewMaterial< BOOST_PP_ARRAY_ELEM(1, elem)< dim > >(section)
#define AKANTU_INTANTIATE_MATERIAL_BY_DIM_TMPL_EACH(r, data, i, elem) \
BOOST_PP_EXPR_IF(BOOST_PP_NOT_EQUAL(0, i), else ) \
if(opt_param == BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem))) { \
registerNewMaterial< BOOST_PP_ARRAY_ELEM(1, data)< BOOST_PP_ARRAY_ELEM(0, data), \
BOOST_PP_SEQ_ENUM(BOOST_PP_TUPLE_ELEM(2, 1, elem)) > >(section); \
}
#define AKANTU_INTANTIATE_MATERIAL_BY_DIM_TMPL(dim, elem) \
BOOST_PP_SEQ_FOR_EACH_I(AKANTU_INTANTIATE_MATERIAL_BY_DIM_TMPL_EACH, \
(2, (dim, BOOST_PP_ARRAY_ELEM(1, elem))), \
BOOST_PP_ARRAY_ELEM(2, elem)) \
else { \
AKANTU_INTANTIATE_MATERIAL_BY_DIM_NO_TMPL(dim, elem); \
}
#define AKANTU_INTANTIATE_MATERIAL_BY_DIM(dim, elem) \
BOOST_PP_IF(BOOST_PP_EQUAL(3, BOOST_PP_ARRAY_SIZE(elem) ), \
AKANTU_INTANTIATE_MATERIAL_BY_DIM_TMPL, \
AKANTU_INTANTIATE_MATERIAL_BY_DIM_NO_TMPL)(dim, elem)
#define AKANTU_INTANTIATE_MATERIAL(elem) \
switch(spatial_dimension) { \
case 1: { AKANTU_INTANTIATE_MATERIAL_BY_DIM(1, elem); break; } \
case 2: { AKANTU_INTANTIATE_MATERIAL_BY_DIM(2, elem); break; } \
case 3: { AKANTU_INTANTIATE_MATERIAL_BY_DIM(3, elem); break; } \
}
#define AKANTU_INTANTIATE_MATERIAL_IF(elem) \
if (mat_type == BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(0, elem))) { \
AKANTU_INTANTIATE_MATERIAL(elem); \
}
#define AKANTU_INTANTIATE_OTHER_MATERIAL(r, data, elem) \
else AKANTU_INTANTIATE_MATERIAL_IF(elem)
#define AKANTU_INSTANTIATE_MATERIALS() \
do { \
AKANTU_INTANTIATE_MATERIAL_IF(BOOST_PP_SEQ_HEAD(AKANTU_MATERIAL_LIST)) \
BOOST_PP_SEQ_FOR_EACH(AKANTU_INTANTIATE_OTHER_MATERIAL, \
_, \
BOOST_PP_SEQ_TAIL(AKANTU_MATERIAL_LIST)) \
else { \
if(getStaticParser().isPermissive()) \
AKANTU_DEBUG_INFO("Malformed material file " << \
": unknown material type '" \
<< mat_type << "'"); \
else \
AKANTU_DEBUG_WARNING("Malformed material file " \
<<": unknown material type " << mat_type \
<< ". This is perhaps a user" \
<< " defined material ?"); \
} \
} while(0)
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::instantiateMaterials() {
std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
sub_sect = this->parser->getSubSections(_st_material);
Parser::const_section_iterator it = sub_sect.first;
for (; it != sub_sect.second; ++it) {
const ParserSection & section = *it;
std::string mat_type = section.getName();
std::string opt_param = section.getOption();
AKANTU_INSTANTIATE_MATERIALS();
}
are_materials_instantiated = true;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assignMaterialToElements(const ElementTypeMapArray<UInt> * filter) {
Material ** mat_val = &(materials.at(0));
Element element;
element.ghost_type = _not_ghost;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, _not_ghost, _ek_not_defined);
if(filter != NULL) {
it = filter->firstType(spatial_dimension, _not_ghost, _ek_not_defined);
end = filter->lastType(spatial_dimension, _not_ghost, _ek_not_defined);
}
// Fill the element material array from the material selector
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it, _not_ghost);
const Array<UInt> * filter_array = NULL;
if (filter != NULL) {
filter_array = &((*filter)(*it, _not_ghost));
nb_element = filter_array->getSize();
}
element.type = *it;
element.kind = mesh.getKind(element.type);
Array<UInt> & mat_indexes = material_index(*it, _not_ghost);
for (UInt el = 0; el < nb_element; ++el) {
if (filter != NULL)
element.element = (*filter_array)(el);
else
element.element = el;
UInt mat_index = (*material_selector)(element);
AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
"The material selector returned an index that does not exists");
mat_indexes(element.element) = mat_index;
}
}
// synchronize the element material arrays
synch_registry->synchronize(_gst_material_id);
/// fill the element filters of the materials using the element_material arrays
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
it = mesh.firstType(spatial_dimension, gt, _ek_not_defined);
end = mesh.lastType(spatial_dimension, gt, _ek_not_defined);
if(filter != NULL) {
it = filter->firstType(spatial_dimension, gt, _ek_not_defined);
end = filter->lastType(spatial_dimension, gt, _ek_not_defined);
}
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it, gt);
const Array<UInt> * filter_array = NULL;
if (filter != NULL) {
filter_array = &((*filter)(*it, gt));
nb_element = filter_array->getSize();
}
Array<UInt> & mat_indexes = material_index(*it, gt);
Array<UInt> & mat_local_num = material_local_numbering(*it, gt);
for (UInt el = 0; el < nb_element; ++el) {
UInt element;
if (filter != NULL) element = (*filter_array)(el);
else element = el;
UInt mat_index = mat_indexes(element);
UInt index = mat_val[mat_index]->addElement(*it, element, gt);
mat_local_num(element) = index;
}
}
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initMaterials() {
AKANTU_DEBUG_ASSERT(materials.size() != 0, "No material to initialize !");
if(!are_materials_instantiated) instantiateMaterials();
this->assignMaterialToElements();
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
/// init internals properties
(*mat_it)->initMaterial();
}
synch_registry->synchronize(_gst_smm_init_mat);
// initialize mass
switch(method) {
case _explicit_lumped_mass:
assembleMassLumped();
break;
case _explicit_consistent_mass:
case _implicit_dynamic:
assembleMass();
break;
case _static:
break;
default:
AKANTU_EXCEPTION("analysis method not recognised by SolidMechanicsModel");
break;
}
// initialize the previous displacement array if at least on material needs it
for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
if (mat.isFiniteDeformation() || mat.isInelasticDeformation()) {
initArraysPreviousDisplacment();
break;
}
}
#ifdef AKANTU_DAMAGE_NON_LOCAL
/// initialize the non-local manager for non-local computations
this->non_local_manager->init();
#endif
}
/* -------------------------------------------------------------------------- */
Int SolidMechanicsModel::getInternalIndexFromID(const ID & id) const {
AKANTU_DEBUG_IN();
std::vector<Material *>::const_iterator first = materials.begin();
std::vector<Material *>::const_iterator last = materials.end();
for (; first != last; ++first)
if ((*first)->getID() == id) {
AKANTU_DEBUG_OUT();
return (first - materials.begin());
}
AKANTU_DEBUG_OUT();
return -1;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::reassignMaterial() {
AKANTU_DEBUG_IN();
std::vector< Array<Element> > element_to_add (materials.size());
std::vector< Array<Element> > element_to_remove(materials.size());
Element element;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
element.ghost_type = ghost_type;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type, _ek_not_defined);
for(; it != end; ++it) {
ElementType type = *it;
element.type = type;
element.kind = Mesh::getKind(type);
UInt nb_element = mesh.getNbElement(type, ghost_type);
Array<UInt> & mat_indexes = material_index(type, ghost_type);
for (UInt el = 0; el < nb_element; ++el) {
element.element = el;
UInt old_material = mat_indexes(el);
UInt new_material = (*material_selector)(element);
if(old_material != new_material) {
element_to_add [new_material].push_back(element);
element_to_remove[old_material].push_back(element);
}
}
}
}
std::vector<Material *>::iterator mat_it;
UInt mat_index = 0;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it, ++mat_index) {
(*mat_it)->removeElements(element_to_remove[mat_index]);
(*mat_it)->addElements (element_to_add[mat_index]);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const ID & material_name,
const GhostType ghost_type) {
AKANTU_DEBUG_ASSERT(prescribed_eigen_grad_u.size() == spatial_dimension * spatial_dimension,
"The prescribed grad_u is not of the good size");
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
if ((*mat_it)->getName() == material_name)
(*mat_it)->applyEigenGradU(prescribed_eigen_grad_u, ghost_type);
}
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh b/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
index c39b04988..c7162df3b 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
@@ -1,106 +1,107 @@
/**
* @file solid_mechanics_model_tmpl.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Nov 24 2011
- * @date last modification: Thu Apr 03 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Nov 13 2015
*
* @brief template part of solid mechanics model
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
template <typename M>
Material & SolidMechanicsModel::registerNewMaterial(const ParserSection & section) {
std::string mat_name;
std::string mat_type = section.getName();
try {
std::string tmp = section.getParameter("name");
mat_name = tmp; /** this can seam weird, but there is an ambiguous operator
* overload that i couldn't solve. @todo remove the
* weirdness of this code
*/
} catch(debug::Exception & ){
AKANTU_DEBUG_ERROR("A material of type \'"
<< mat_type
<< "\' in the input file has been defined without a name!");
}
AKANTU_DEBUG_ASSERT(materials_names_to_id.find(mat_name) == materials_names_to_id.end(),
"A material with this name '" << mat_name
<< "' has already been registered. "
<< "Please use unique names for materials");
UInt mat_count = materials.size();
materials_names_to_id[mat_name] = mat_count;
std::stringstream sstr_mat; sstr_mat << this->id << ":" << mat_count << ":" << mat_type;
ID mat_id = sstr_mat.str();
Material * material;
material = new M(*this, mat_id);
materials.push_back(material);
material->parseSection(section);
return *material;
}
/* -------------------------------------------------------------------------- */
template <typename M>
Material & SolidMechanicsModel::registerNewEmptyMaterial(const std::string & mat_name) {
AKANTU_DEBUG_ASSERT(materials_names_to_id.find(mat_name) == materials_names_to_id.end(),
"A material with this name '" << mat_name
<< "' has already been registered. "
<< "Please use unique names for materials");
UInt mat_count = materials.size();
materials_names_to_id[mat_name] = mat_count;
std::stringstream sstr_mat; sstr_mat << id << ":" << mat_count << ":" << mat_name;
ID mat_id = sstr_mat.str();
Material * material;
material = new M(*this, mat_id);
materials.push_back(material);
return *material;
}
/* -------------------------------------------------------------------------- */
template <typename M>
void SolidMechanicsModel::registerNewCustomMaterials(const ID & mat_type) {
std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
sub_sect = getStaticParser().getSubSections(_st_material);
Parser::const_section_iterator it = sub_sect.first;
for (; it != sub_sect.second; ++it) {
if(it->getName() == mat_type) {
registerNewMaterial<M>(*it);
}
}
}
/* -------------------------------------------------------------------------- */
diff --git a/src/model/structural_mechanics/structural_mechanics_model.cc b/src/model/structural_mechanics/structural_mechanics_model.cc
index 557c0fd96..102f82f8f 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model.cc
@@ -1,1148 +1,1149 @@
/**
* @file structural_mechanics_model.cc
*
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Damien Spielmann <damien.spielmann@epfl.ch>
- * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
- * @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Fri Jul 15 2011
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Model implementation for StucturalMechanics elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "structural_mechanics_model.hh"
#include "group_manager_inline_impl.cc"
#include "dumpable_inline_impl.hh"
#include "aka_math.hh"
#include "integration_scheme_2nd_order.hh"
#include "static_communicator.hh"
#include "sparse_matrix.hh"
#include "solver.hh"
#ifdef AKANTU_USE_MUMPS
#include "solver_mumps.hh"
#endif
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
# include "dumper_elemental_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const StructuralMechanicsModelOptions default_structural_mechanics_model_options(_static);
/* -------------------------------------------------------------------------- */
StructuralMechanicsModel::StructuralMechanicsModel(Mesh & mesh,
UInt dim,
const ID & id,
const MemoryID & memory_id) :
Model(mesh, dim, id, memory_id),
time_step(NAN), f_m2a(1.0),
stress("stress", id, memory_id),
element_material("element_material", id, memory_id),
set_ID("beam sets", id, memory_id),
stiffness_matrix(NULL),
mass_matrix(NULL),
velocity_damping_matrix(NULL),
jacobian_matrix(NULL),
solver(NULL),
rotation_matrix("rotation_matices", id, memory_id),
increment_flag(false),
integrator(NULL) {
AKANTU_DEBUG_IN();
registerFEEngineObject<MyFEEngineType>("StructuralMechanicsFEEngine", mesh, spatial_dimension);
this->displacement_rotation = NULL;
this->mass = NULL;
this->velocity = NULL;
this->acceleration = NULL;
this->force_momentum = NULL;
this->residual = NULL;
this->blocked_dofs = NULL;
this->increment = NULL;
this->previous_displacement = NULL;
if(spatial_dimension == 2)
nb_degree_of_freedom = 3;
else if (spatial_dimension == 3)
nb_degree_of_freedom = 6;
else {
AKANTU_DEBUG_TO_IMPLEMENT();
}
this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_structural);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
StructuralMechanicsModel::~StructuralMechanicsModel() {
AKANTU_DEBUG_IN();
delete integrator;
delete solver;
delete stiffness_matrix;
delete jacobian_matrix;
delete mass_matrix;
delete velocity_damping_matrix;
AKANTU_DEBUG_OUT();
}
void StructuralMechanicsModel::setTimeStep(Real time_step) {
this->time_step = time_step;
#if defined(AKANTU_USE_IOHELPER)
this->mesh.getDumper().setTimeStep(time_step);
#endif
}
/* -------------------------------------------------------------------------- */
/* Initialisation */
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initFull(const ModelOptions & options) {
const StructuralMechanicsModelOptions & stmm_options =
dynamic_cast<const StructuralMechanicsModelOptions &>(options);
method = stmm_options.analysis_method;
initModel();
initArrays();
displacement_rotation->clear();
velocity ->clear();
acceleration ->clear();
force_momentum ->clear();
residual ->clear();
blocked_dofs ->clear();
increment ->clear();
Mesh::type_iterator it = getFEEngine().getMesh().firstType(spatial_dimension, _not_ghost, _ek_structural);
Mesh::type_iterator end = getFEEngine().getMesh().lastType(spatial_dimension, _not_ghost, _ek_structural);
for (; it != end; ++it) {
computeRotationMatrix(*it);
}
switch(method) {
case _implicit_dynamic:
initImplicit();
break;
case _static:
initSolver();
break;
default:
AKANTU_EXCEPTION("analysis method not recognised by StructuralMechanicsModel");
break;
}
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initArrays() {
AKANTU_DEBUG_IN();
UInt nb_nodes = getFEEngine().getMesh().getNbNodes();
std::stringstream sstr_disp; sstr_disp << id << ":displacement";
std::stringstream sstr_velo; sstr_velo << id << ":velocity";
std::stringstream sstr_acce; sstr_acce << id << ":acceleration";
std::stringstream sstr_forc; sstr_forc << id << ":force";
std::stringstream sstr_resi; sstr_resi << id << ":residual";
std::stringstream sstr_boun; sstr_boun << id << ":blocked_dofs";
std::stringstream sstr_incr; sstr_incr << id << ":increment";
displacement_rotation = &(alloc<Real>(sstr_disp.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
velocity = &(alloc<Real>(sstr_velo.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
acceleration = &(alloc<Real>(sstr_acce.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
force_momentum = &(alloc<Real>(sstr_forc.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
residual = &(alloc<Real>(sstr_resi.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
blocked_dofs = &(alloc<bool>(sstr_boun.str(), nb_nodes, nb_degree_of_freedom, false));
increment = &(alloc<Real>(sstr_incr.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
Mesh::type_iterator it = getFEEngine().getMesh().firstType(spatial_dimension, _not_ghost, _ek_structural);
Mesh::type_iterator end = getFEEngine().getMesh().lastType(spatial_dimension, _not_ghost, _ek_structural);
for (; it != end; ++it) {
UInt nb_element = getFEEngine().getMesh().getNbElement(*it);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(*it);
element_material.alloc(nb_element, 1, *it, _not_ghost);
set_ID.alloc(nb_element, 1, *it, _not_ghost);
UInt size = getTangentStiffnessVoigtSize(*it);
stress.alloc(nb_element * nb_quadrature_points, size , *it, _not_ghost);
}
dof_synchronizer = new DOFSynchronizer(getFEEngine().getMesh(), nb_degree_of_freedom);
dof_synchronizer->initLocalDOFEquationNumbers();
dof_synchronizer->initGlobalDOFEquationNumbers();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initModel() {
getFEEngine().initShapeFunctions(_not_ghost);
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initSolver(__attribute__((unused)) SolverOptions & options) {
AKANTU_DEBUG_IN();
const Mesh & mesh = getFEEngine().getMesh();
#if !defined(AKANTU_USE_MUMPS) // or other solver in the future \todo add AKANTU_HAS_SOLVER in CMake
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#else
UInt nb_global_node = mesh.getNbGlobalNodes();
std::stringstream sstr; sstr << id << ":jacobian_matrix";
jacobian_matrix = new SparseMatrix(nb_global_node * nb_degree_of_freedom, _symmetric, sstr.str(), memory_id);
jacobian_matrix->buildProfile(mesh, *dof_synchronizer, nb_degree_of_freedom);
std::stringstream sstr_sti; sstr_sti << id << ":stiffness_matrix";
stiffness_matrix = new SparseMatrix(*jacobian_matrix, sstr_sti.str(), memory_id);
#ifdef AKANTU_USE_MUMPS
std::stringstream sstr_solv; sstr_solv << id << ":solver";
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
dof_synchronizer->initScatterGatherCommunicationScheme();
#else
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#endif //AKANTU_USE_MUMPS
solver->initialize(options);
#endif //AKANTU_HAS_SOLVER
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initImplicit(bool dynamic, SolverOptions & solver_options) {
AKANTU_DEBUG_IN();
if (!increment) setIncrementFlagOn();
initSolver(solver_options);
if(integrator) delete integrator;
integrator = new TrapezoidalRule2();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize(const ElementType & type) {
UInt size;
#define GET_TANGENT_STIFFNESS_VOIGT_SIZE(type) \
size = getTangentStiffnessVoigtSize<type>();
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_TANGENT_STIFFNESS_VOIGT_SIZE);
#undef GET_TANGENT_STIFFNESS_VOIGT_SIZE
return size;
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::assembleStiffnessMatrix() {
AKANTU_DEBUG_IN();
stiffness_matrix->clear();
Mesh::type_iterator it = getFEEngine().getMesh().firstType(spatial_dimension, _not_ghost, _ek_structural);
Mesh::type_iterator end = getFEEngine().getMesh().lastType(spatial_dimension, _not_ghost, _ek_structural);
for (; it != end; ++it) {
ElementType type = *it;
#define ASSEMBLE_STIFFNESS_MATRIX(type) \
assembleStiffnessMatrix<type>();
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(ASSEMBLE_STIFFNESS_MATRIX);
#undef ASSEMBLE_STIFFNESS_MATRIX
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_2>(Array<Real> & rotations){
ElementType type = _bernoulli_beam_2;
Mesh & mesh = getFEEngine().getMesh();
UInt nb_element = mesh.getNbElement(type);
Array<UInt>::iterator< Vector<UInt> > connec_it = mesh.getConnectivity(type).begin(2);
Array<Real>::vector_iterator nodes_it = mesh.getNodes().begin(spatial_dimension);
Array<Real>::matrix_iterator R_it = rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
for (UInt e = 0; e < nb_element; ++e, ++R_it, ++connec_it) {
Matrix<Real> & R = *R_it;
Vector<UInt> & connec = *connec_it;
Vector<Real> x2;
x2 = nodes_it[connec(1)]; // X2
Vector<Real> x1;
x1 = nodes_it[connec(0)]; // X1
Real le = x1.distance(x2);
Real c = (x2(0) - x1(0)) / le;
Real s = (x2(1) - x1(1)) / le;
/// Definition of the rotation matrix
R(0,0) = c; R(0,1) = s; R(0,2) = 0.;
R(1,0) = -s; R(1,1) = c; R(1,2) = 0.;
R(2,0) = 0.; R(2,1) = 0.; R(2,2) = 1.;
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_3>(Array<Real> & rotations){
ElementType type = _bernoulli_beam_3;
Mesh & mesh = getFEEngine().getMesh();
UInt nb_element = mesh.getNbElement(type);
Array<Real>::vector_iterator n_it = mesh.getNormals(type).begin(spatial_dimension);
Array<UInt>::iterator< Vector<UInt> > connec_it = mesh.getConnectivity(type).begin(2);
Array<Real>::vector_iterator nodes_it = mesh.getNodes().begin(spatial_dimension);
Matrix<Real> Pe (spatial_dimension, spatial_dimension);
Matrix<Real> Pg (spatial_dimension, spatial_dimension);
Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension);
Vector<Real> x_n(spatial_dimension); // x vect n
Array<Real>::matrix_iterator R_it =
rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
for (UInt e=0 ; e < nb_element; ++e, ++n_it, ++connec_it, ++R_it) {
Vector<Real> & n = *n_it;
Matrix<Real> & R = *R_it;
Vector<UInt> & connec = *connec_it;
Vector<Real> x;
x = nodes_it[connec(1)]; // X2
Vector<Real> y;
y = nodes_it[connec(0)]; // X1
Real l = x.distance(y);
x -= y; // X2 - X1
x_n.crossProduct(x, n);
Pe.eye();
Pe(0, 0) *= l;
Pe(1, 1) *= -l;
Pg(0,0) = x(0); Pg(0,1) = x_n(0); Pg(0,2) = n(0);
Pg(1,0) = x(1); Pg(1,1) = x_n(1); Pg(1,2) = n(1);
Pg(2,0) = x(2); Pg(2,1) = x_n(2); Pg(2,2) = n(2);
inv_Pg.inverse(Pg);
Pe *= inv_Pg;
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
R(i, j) = Pe(i, j);
R(i + spatial_dimension,j + spatial_dimension) = Pe(i, j);
}
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeRotationMatrix<_kirchhoff_shell>(Array<Real> & rotations){
ElementType type = _kirchhoff_shell;
Mesh & mesh = getFEEngine().getMesh();
UInt nb_element = mesh.getNbElement(type);
Array<UInt>::iterator< Vector<UInt> > connec_it = mesh.getConnectivity(type).begin(3);
Array<Real>::vector_iterator nodes_it = mesh.getNodes().begin(spatial_dimension);
Matrix<Real> Pe (spatial_dimension, spatial_dimension);
Matrix<Real> Pg (spatial_dimension, spatial_dimension);
Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator R_it =
rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
for (UInt e=0 ; e < nb_element; ++e, ++connec_it, ++R_it) {
Pe.eye();
Matrix<Real> & R = *R_it;
Vector<UInt> & connec = *connec_it;
Vector<Real> x2;
x2 = nodes_it[connec(1)]; // X2
Vector<Real> x1;
x1 = nodes_it[connec(0)]; // X1
Vector<Real> x3;
x3 = nodes_it[connec(2)]; // X3
Vector<Real> Pg_col_1=x2-x1;
Vector<Real> Pg_col_2 = x3-x1;
Vector<Real> Pg_col_3(spatial_dimension);
Pg_col_3.crossProduct(Pg_col_1, Pg_col_2);
for (UInt i = 0; i <spatial_dimension; ++i) {
Pg(i,0) = Pg_col_1(i);
Pg(i,1) = Pg_col_2(i);
Pg(i,2) = Pg_col_3(i);
}
inv_Pg.inverse(Pg);
// Pe *= inv_Pg;
Pe.eye();
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
R(i, j) = Pe(i, j);
R(i + spatial_dimension,j + spatial_dimension) = Pe(i, j);
}
}
}
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::computeRotationMatrix(const ElementType & type) {
Mesh & mesh = getFEEngine().getMesh();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_element = mesh.getNbElement(type);
if(!rotation_matrix.exists(type)) {
rotation_matrix.alloc(nb_element,
nb_degree_of_freedom*nb_nodes_per_element * nb_degree_of_freedom*nb_nodes_per_element,
type);
} else {
rotation_matrix(type).resize(nb_element);
}
rotation_matrix(type).clear();
Array<Real>rotations(nb_element, nb_degree_of_freedom * nb_degree_of_freedom);
rotations.clear();
#define COMPUTE_ROTATION_MATRIX(type) \
computeRotationMatrix<type>(rotations);
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_ROTATION_MATRIX);
#undef COMPUTE_ROTATION_MATRIX
Array<Real>::matrix_iterator R_it = rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
Array<Real>::matrix_iterator T_it =
rotation_matrix(type).begin(nb_degree_of_freedom*nb_nodes_per_element,
nb_degree_of_freedom*nb_nodes_per_element);
for (UInt el = 0; el < nb_element; ++el, ++R_it, ++T_it) {
Matrix<Real> & T = *T_it;
Matrix<Real> & R = *R_it;
T.clear();
for (UInt k = 0; k < nb_nodes_per_element; ++k){
for (UInt i = 0; i < nb_degree_of_freedom; ++i)
for (UInt j = 0; j < nb_degree_of_freedom; ++j)
T(k*nb_degree_of_freedom + i, k*nb_degree_of_freedom + j) = R(i, j);
}
}
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::computeStresses() {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = getFEEngine().getMesh().firstType(spatial_dimension, _not_ghost, _ek_structural);
Mesh::type_iterator end = getFEEngine().getMesh().lastType(spatial_dimension, _not_ghost, _ek_structural);
for (; it != end; ++it) {
ElementType type = *it;
#define COMPUTE_STRESS_ON_QUAD(type) \
computeStressOnQuad<type>();
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_STRESS_ON_QUAD);
#undef COMPUTE_STRESS_ON_QUAD
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::updateResidual() {
AKANTU_DEBUG_IN();
residual->copy(*force_momentum);
Array<Real> ku(*displacement_rotation, true);
ku *= *stiffness_matrix;
*residual -= ku;
this->updateResidualInternal();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::implicitPred() {
AKANTU_DEBUG_IN();
if(previous_displacement) previous_displacement->copy(*displacement_rotation);
if(method == _implicit_dynamic)
integrator->integrationSchemePred(time_step,
*displacement_rotation,
*velocity,
*acceleration,
*blocked_dofs);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::implicitCorr() {
AKANTU_DEBUG_IN();
Real * incr_val = increment->storage();
bool * boun_val = blocked_dofs->storage();
UInt nb_nodes = displacement_rotation->getSize();
for (UInt j = 0; j < nb_nodes * nb_degree_of_freedom; ++j, ++incr_val, ++boun_val){
*incr_val *= (1. - *boun_val);
}
if(method == _implicit_dynamic) {
integrator->integrationSchemeCorrDispl(time_step,
*displacement_rotation,
*velocity,
*acceleration,
*blocked_dofs,
*increment);
} else {
Real * disp_val = displacement_rotation->storage();
incr_val = increment->storage();
for (UInt j = 0; j < nb_nodes *nb_degree_of_freedom; ++j, ++disp_val, ++incr_val){
*disp_val += *incr_val;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::updateResidualInternal() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Update the residual");
// f = f_ext - f_int - Ma - Cv = r - Ma - Cv;
if(method != _static) {
// f -= Ma
if(mass_matrix) {
// if full mass_matrix
Array<Real> * Ma = new Array<Real>(*acceleration, true, "Ma");
*Ma *= *mass_matrix;
/// \todo check unit conversion for implicit dynamics
// *Ma /= f_m2a
*residual -= *Ma;
delete Ma;
} else if (mass) {
// else lumped mass
UInt nb_nodes = acceleration->getSize();
UInt nb_degree_of_freedom = acceleration->getNbComponent();
Real * mass_val = mass->storage();
Real * accel_val = acceleration->storage();
Real * res_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*res_val -= *accel_val * *mass_val /f_m2a;
}
blocked_dofs_val++;
res_val++;
mass_val++;
accel_val++;
}
} else {
AKANTU_DEBUG_ERROR("No function called to assemble the mass matrix.");
}
// f -= Cv
if(velocity_damping_matrix) {
Array<Real> * Cv = new Array<Real>(*velocity);
*Cv *= *velocity_damping_matrix;
*residual -= *Cv;
delete Cv;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::setIncrementFlagOn() {
AKANTU_DEBUG_IN();
if(!increment) {
UInt nb_nodes = mesh.getNbNodes();
std::stringstream sstr_inc; sstr_inc << id << ":increment";
increment = &(alloc<Real>(sstr_inc.str(), nb_nodes, spatial_dimension, 0.));
}
increment_flag = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::solve() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Solving an implicit step.");
UInt nb_nodes = displacement_rotation->getSize();
/// todo residual = force - Kxr * d_bloq
jacobian_matrix->copyContent(*stiffness_matrix);
jacobian_matrix->applyBoundary(*blocked_dofs);
jacobian_matrix->saveMatrix("Kbound.mtx");
increment->clear();
solver->setRHS(*residual);
solver->factorize();
solver->solve(*increment);
Real * increment_val = increment->storage();
Real * displacement_val = displacement_rotation->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*displacement_val += *increment_val;
}
else {
*increment_val = 0.0;
}
displacement_val++;
blocked_dofs_val++;
increment_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
bool StructuralMechanicsModel::testConvergence<_scc_increment>(Real tolerance, Real & error){
AKANTU_DEBUG_IN();
UInt nb_nodes = displacement_rotation->getSize();
UInt nb_degree_of_freedom = displacement_rotation->getNbComponent();
error = 0;
Real norm[2] = {0., 0.};
Real * increment_val = increment->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
Real * displacement_val = displacement_rotation->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val)) {
norm[0] += *increment_val * *increment_val;
norm[1] += *displacement_val * *displacement_val;
}
blocked_dofs_val++;
increment_val++;
displacement_val++;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(norm, 2, _so_sum);
norm[0] = sqrt(norm[0]);
norm[1] = sqrt(norm[1]);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm[0]), "Something went wrong in the solve phase");
AKANTU_DEBUG_OUT();
if(norm[1] > Math::getTolerance())
error = norm[0] / norm[1];
else
error = norm[0]; //In case the total displacement is zero!
return (error < tolerance);
}
/* -------------------------------------------------------------------------- */
template<>
bool StructuralMechanicsModel::testConvergence<_scc_residual>(Real tolerance, Real & norm) {
AKANTU_DEBUG_IN();
UInt nb_nodes = residual->getSize();
norm = 0;
Real * residual_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
if(is_local_node) {
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val)) {
norm += *residual_val * *residual_val;
}
blocked_dofs_val++;
residual_val++;
}
} else {
blocked_dofs_val += spatial_dimension;
residual_val += spatial_dimension;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum);
norm = sqrt(norm);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
AKANTU_DEBUG_OUT();
return (norm < tolerance);
}
/* -------------------------------------------------------------------------- */
bool StructuralMechanicsModel::testConvergenceIncrement(Real tolerance) {
Real error;
bool tmp = testConvergenceIncrement(tolerance, error);
AKANTU_DEBUG_INFO("Norm of increment : " << error);
return tmp;
}
/* -------------------------------------------------------------------------- */
bool StructuralMechanicsModel::testConvergenceIncrement(Real tolerance, Real & error) {
AKANTU_DEBUG_IN();
Mesh & mesh= getFEEngine().getMesh();
UInt nb_nodes = displacement_rotation->getSize();
UInt nb_degree_of_freedom = displacement_rotation->getNbComponent();
Real norm = 0;
Real * increment_val = increment->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val) && is_local_node) {
norm += *increment_val * *increment_val;
}
blocked_dofs_val++;
increment_val++;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum);
error = sqrt(norm);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
AKANTU_DEBUG_OUT();
return (error < tolerance);
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_2>(Array<Real> & tangent_moduli) {
UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2);
UInt tangent_size = 2;
Array<Real>::matrix_iterator D_it = tangent_moduli.begin(tangent_size, tangent_size);
Array<UInt> & el_mat = element_material(_bernoulli_beam_2, _not_ghost);
for (UInt e = 0; e < nb_element; ++e) {
UInt mat = el_mat(e);
Real E = materials[mat].E;
Real A = materials[mat].A;
Real I = materials[mat].I;
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
Matrix<Real> & D = *D_it;
D(0,0) = E * A;
D(1,1) = E * I;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_3>(Array<Real> & tangent_moduli) {
UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3);
UInt tangent_size = 4;
Array<Real>::matrix_iterator D_it = tangent_moduli.begin(tangent_size, tangent_size);
for (UInt e = 0; e < nb_element; ++e) {
UInt mat = element_material(_bernoulli_beam_3, _not_ghost)(e);
Real E = materials[mat].E;
Real A = materials[mat].A;
Real Iz = materials[mat].Iz;
Real Iy = materials[mat].Iy;
Real GJ = materials[mat].GJ;
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
Matrix<Real> & D = *D_it;
D(0,0) = E * A;
D(1,1) = E * Iz;
D(2,2) = E * Iy;
D(3,3) = GJ;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeTangentModuli<_kirchhoff_shell>(Array<Real> & tangent_moduli) {
UInt nb_element = getFEEngine().getMesh().getNbElement(_kirchhoff_shell);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_kirchhoff_shell);
UInt tangent_size = 6;
Array<Real>::matrix_iterator D_it = tangent_moduli.begin(tangent_size, tangent_size);
for (UInt e = 0; e < nb_element; ++e) {
UInt mat = element_material(_kirchhoff_shell, _not_ghost)(e);
Real E = materials[mat].E;
Real nu = materials[mat].nu;
Real t = materials[mat].t;
Real HH=E*t/(1-nu*nu);
Real DD=E*t*t*t/(12*(1-nu*nu));
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
Matrix<Real> & D = *D_it;
D(0,0) = HH;
D(0,1) = HH*nu;
D(1,0) = HH*nu;
D(1,1) = HH;
D(2,2) = HH*(1-nu)/2;
D(3,3) = DD;
D(3,4) = DD*nu;
D(4,3) = DD*nu;
D(4,4) = DD;
D(5,5) = DD*(1-nu)/2;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix<_bernoulli_beam_2>(Array<Real> & b, bool local) {
UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_bernoulli_beam_2);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2);
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
Array<Real>::const_vector_iterator shape_Np = fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 0).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Mpp = fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 1).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Lpp = fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 2).begin(nb_nodes_per_element);
UInt tangent_size = getTangentStiffnessVoigtSize<_bernoulli_beam_2>();
UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom;
b.clear();
Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size);
for (UInt e = 0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quadrature_points; ++q) {
Matrix<Real> & B = *B_it;
const Vector<Real> & Np = *shape_Np;
const Vector<Real> & Lpp = *shape_Lpp;
const Vector<Real> & Mpp = *shape_Mpp;
B(0,0) = Np(0);
B(0,3) = Np(1);
B(1,1) = Mpp(0);
B(1,2) = Lpp(0);
B(1,4) = Mpp(1);
B(1,5) = Lpp(1);
++B_it;
++shape_Np;
++shape_Mpp;
++shape_Lpp;
}
// ++R_it;
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix<_bernoulli_beam_3>(Array<Real> & b, bool local) {
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_bernoulli_beam_3);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3);
Array<Real>::const_vector_iterator shape_Np = fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 0).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Mpp = fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 1).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Lpp = fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 2).begin(nb_nodes_per_element);
UInt tangent_size = getTangentStiffnessVoigtSize<_bernoulli_beam_3>();
UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom;
b.clear();
Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size);
for (UInt e = 0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quadrature_points; ++q) {
Matrix<Real> & B = *B_it;
const Vector<Real> & Np = *shape_Np;
const Vector<Real> & Lpp = *shape_Lpp;
const Vector<Real> & Mpp = *shape_Mpp;
B(0,0) = Np(0);
B(0,6) = Np(1);
B(1,1) = Mpp(0);
B(1,5) = Lpp(0);
B(1,7) = Mpp(1);
B(1,11) = Lpp(1);
B(2,2) = Mpp(0);
B(2,4) = -Lpp(0);
B(2,8) = Mpp(1);
B(2,10) = -Lpp(1);
B(3,3) = Np(0);
B(3,9) = Np(1);
++B_it;
++shape_Np;
++shape_Mpp;
++shape_Lpp;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix<_kirchhoff_shell>(Array<Real> & b, bool local) {
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_element = getFEEngine().getMesh().getNbElement(_kirchhoff_shell);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_kirchhoff_shell);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_kirchhoff_shell);
Array<Real>::const_matrix_iterator shape_Np = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 0).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Nx1p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 1).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Nx2p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 2).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Nx3p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 3).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Ny1p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 4).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Ny2p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 5).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Ny3p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 6).begin(2,nb_nodes_per_element);
UInt tangent_size = getTangentStiffnessVoigtSize<_kirchhoff_shell>();
UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom;
b.clear();
Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size);
for (UInt e = 0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quadrature_points; ++q) {
Matrix<Real> & B = *B_it;
const Matrix<Real> & Np = *shape_Np;
const Matrix<Real> & Nx1p = *shape_Nx1p;
const Matrix<Real> & Nx2p = *shape_Nx2p;
const Matrix<Real> & Nx3p = *shape_Nx3p;
const Matrix<Real> & Ny1p = *shape_Ny1p;
const Matrix<Real> & Ny2p = *shape_Ny2p;
const Matrix<Real> & Ny3p = *shape_Ny3p;
B(0,0) = Np(0,0);
B(0,6) = Np(0,1);
B(0,12) = Np(0,2);
B(1,1) = Np(1,0);
B(1,7) = Np(1,1);
B(1,13) = Np(1,2);
B(2,0) = Np(1,0);
B(2,1) = Np(0,0);
B(2,6) = Np(1,1);
B(2,7) = Np(0,1);
B(2,12) = Np(1,2);
B(2,13) = Np(0,2);
B(3,2) = Nx1p(0,0);
B(3,3) = Nx2p(0,0);
B(3,4) = Nx3p(0,0);
B(3,8) = Nx1p(0,1);
B(3,9) = Nx2p(0,1);
B(3,10) = Nx3p(0,1);
B(3,14) = Nx1p(0,2);
B(3,15) = Nx2p(0,2);
B(3,16) = Nx3p(0,2);
B(4,2) = Ny1p(1,0);
B(4,3) = Ny2p(1,0);
B(4,4) = Ny3p(1,0);
B(4,8) = Ny1p(1,1);
B(4,9) = Ny2p(1,1);
B(4,10) = Ny3p(1,1);
B(4,14) = Ny1p(1,2);
B(4,15) = Ny2p(1,2);
B(4,16) = Ny3p(1,2);
B(5,2) = Nx1p(1,0) + Ny1p(0,0);
B(5,3) = Nx2p(1,0) + Ny2p(0,0);
B(5,4) = Nx3p(1,0) + Ny3p(0,0);
B(5,8) = Nx1p(1,1) + Ny1p(0,1);
B(5,9) = Nx2p(1,1) + Ny2p(0,1);
B(5,10) = Nx3p(1,1) + Ny3p(0,1);
B(5,14) = Nx1p(1,2) + Ny1p(0,2);
B(5,15) = Nx2p(1,2) + Ny2p(0,2);
B(5,16) = Nx3p(1,2) + Ny3p(0,2);
++B_it;
++shape_Np;
++shape_Nx1p;
++shape_Nx2p;
++shape_Nx3p;
++shape_Ny1p;
++shape_Ny2p;
++shape_Ny3p;
}
}
}
/* -------------------------------------------------------------------------- */
dumper::Field * StructuralMechanicsModel
::createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
std::map<std::string,Array<bool>* > uint_nodal_fields;
uint_nodal_fields["blocked_dofs" ] = blocked_dofs;
dumper::Field * field = NULL;
field = mesh.createNodalField(uint_nodal_fields[field_name],group_name);
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * StructuralMechanicsModel
::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
UInt n;
if(spatial_dimension == 2) {
n = 2;
} else n = 3;
dumper::Field * field = NULL;
if (field_name == "displacement"){
field = mesh.createStridedNodalField(displacement_rotation,group_name,n,0,padding_flag);
}
if (field_name == "rotation"){
field = mesh.createStridedNodalField(displacement_rotation,group_name,
nb_degree_of_freedom-n,n,padding_flag);
}
if (field_name == "force"){
field = mesh.createStridedNodalField(force_momentum,group_name,n,0,padding_flag);
}
if (field_name == "momentum"){
field = mesh.createStridedNodalField(force_momentum,group_name,
nb_degree_of_freedom-n,n,padding_flag);
}
if (field_name == "residual"){
field = mesh.createNodalField(residual,group_name,padding_flag);
}
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * StructuralMechanicsModel
::createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const ElementKind & kind,
const std::string & fe_engine_id){
dumper::Field * field = NULL;
if(field_name == "element_index_by_material")
field = mesh.createElementalField<UInt, Vector, dumper::ElementalField >(field_name,group_name,this->spatial_dimension,kind);
return field;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/structural_mechanics/structural_mechanics_model.hh b/src/model/structural_mechanics/structural_mechanics_model.hh
index 9a214db8e..86514f29d 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.hh
+++ b/src/model/structural_mechanics/structural_mechanics_model.hh
@@ -1,401 +1,402 @@
/**
* @file structural_mechanics_model.hh
*
+ * @author Fabian Barras <fabian.barras@epfl.ch>
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
- * @author Damien Spielmann <damien.spielmann@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation: Fri Jul 15 2011
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Wed Apr 22 2015
*
* @brief Particular implementation of the structural elements in the StructuralMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__
#define __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "model.hh"
#include "integrator_gauss.hh"
#include "shape_linked.hh"
#include "aka_types.hh"
#include "dumpable.hh"
#include "solver.hh"
#include "integration_scheme_2nd_order.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class SparseMatrix;
}
__BEGIN_AKANTU__
struct StructuralMaterial {
Real E;
Real A;
Real I;
Real Iz;
Real Iy;
Real GJ;
Real rho;
Real t;
Real nu;
};
struct StructuralMechanicsModelOptions : public ModelOptions {
StructuralMechanicsModelOptions(AnalysisMethod analysis_method = _static) :
analysis_method(analysis_method) {}
AnalysisMethod analysis_method;
};
extern const StructuralMechanicsModelOptions default_structural_mechanics_model_options;
class StructuralMechanicsModel : public Model {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural> MyFEEngineType;
StructuralMechanicsModel(Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "structural_mechanics_model",
const MemoryID & memory_id = 0);
virtual ~StructuralMechanicsModel();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize fully the model
void initFull(const ModelOptions & options = default_structural_mechanics_model_options);
/// initialize the internal vectors
void initArrays();
/// initialize the model
void initModel();
/// initialize the solver
void initSolver(SolverOptions & options = _solver_no_options);
/// initialize the stuff for the implicit solver
void initImplicit(bool dynamic = false,
SolverOptions & solver_options = _solver_no_options);
/// compute the stresses per elements
void computeStresses();
/// assemble the stiffness matrix
void assembleStiffnessMatrix();
/// assemble the mass matrix for consistent mass resolutions
void assembleMass();
/// implicit time integration predictor
void implicitPred();
/// implicit time integration corrector
void implicitCorr();
/// update the residual vector
void updateResidual();
/// solve the system
void solve();
bool testConvergenceIncrement(Real tolerance);
bool testConvergenceIncrement(Real tolerance, Real & error);
virtual void printself(std::ostream & stream, int indent = 0) const {};
void computeRotationMatrix(const ElementType & type);
protected:
UInt getTangentStiffnessVoigtSize(const ElementType & type);
/// compute Rotation Matrices
template<const ElementType type>
void computeRotationMatrix(Array<Real> & rotations) {};
/// compute A and solve @f[ A\delta u = f_ext - f_int @f]
template<NewmarkBeta::IntegrationSchemeCorrectorType type>
void solve(Array<Real> & increment, Real block_val = 1.);
/* ------------------------------------------------------------------------ */
/* Mass (structural_mechanics_model_mass.cc) */
/* ------------------------------------------------------------------------ */
/// assemble the mass matrix for either _ghost or _not_ghost elements
void assembleMass(GhostType ghost_type);
/// computes rho
void computeRho(Array<Real> & rho,
ElementType type,
GhostType ghost_type);
/// finish the computation of residual to solve in increment
void updateResidualInternal();
/* ------------------------------------------------------------------------ */
private:
template<ElementType type>
inline UInt getTangentStiffnessVoigtSize();
template <ElementType type>
void assembleStiffnessMatrix();
template <ElementType type>
void assembleMass();
template<ElementType type>
void computeStressOnQuad();
template <ElementType type>
void computeTangentModuli(Array<Real> & tangent_moduli);
template <ElementType type>
void transferBMatrixToSymVoigtBMatrix(Array<Real> & B, bool local = false);
template <ElementType type>
void transferNMatrixToSymVoigtNMatrix(Array<Real> & N_matrix);
/* ------------------------------------------------------------------------ */
/* Dumpable interface */
/* ------------------------------------------------------------------------ */
public:
virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field * createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const ElementKind & kind,
const std::string & fe_engine_id = "");
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// set the value of the time step
void setTimeStep(Real time_step);
/// return the dimension of the system space
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// get the StructuralMechanicsModel::displacement vector
AKANTU_GET_MACRO(Displacement, *displacement_rotation, Array<Real> &);
/// get the StructuralMechanicsModel::velocity vector
AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &);
/// get the StructuralMechanicsModel::acceleration vector, updated by
/// StructuralMechanicsModel::updateAcceleration
AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
/// get the StructuralMechanicsModel::force vector (boundary forces)
AKANTU_GET_MACRO(Force, *force_momentum, Array<Real> &);
/// get the StructuralMechanicsModel::residual vector, computed by StructuralMechanicsModel::updateResidual
AKANTU_GET_MACRO(Residual, *residual, const Array<Real> &);
/// get the StructuralMechanicsModel::boundary vector
AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(RotationMatrix, rotation_matrix, Real);
AKANTU_GET_MACRO(StiffnessMatrix, *stiffness_matrix, const SparseMatrix &);
AKANTU_GET_MACRO(MassMatrix, *mass_matrix, const SparseMatrix &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(ElementMaterial, element_material, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Set_ID, set_ID, UInt);
void addMaterial(StructuralMaterial & material) { materials.push_back(material); }
/**
* @brief set the StructuralMechanicsModel::increment_flag to on, the activate the
* update of the StructuralMechanicsModel::increment vector
*/
void setIncrementFlagOn();
/* ------------------------------------------------------------------------ */
/* Boundaries (structural_mechanics_model_boundary.cc) */
/* ------------------------------------------------------------------------ */
public:
/// Compute Linear load function set in global axis
template <ElementType type>
void computeForcesByGlobalTractionArray(const Array<Real> & tractions);
/// Compute Linear load function set in local axis
template <ElementType type>
void computeForcesByLocalTractionArray(const Array<Real> & tractions);
/// compute force vector from a function(x,y,momentum) that describe stresses
template <ElementType type>
void computeForcesFromFunction(BoundaryFunction in_function,
BoundaryFunctionType function_type);
/**
* solve a step (predictor + convergence loop + corrector) using the
* the given convergence method (see akantu::SolveConvergenceMethod)
* and the given convergence criteria (see
* akantu::SolveConvergenceCriteria)
**/
template<SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance,
UInt max_iteration = 100);
template<SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance,
Real & error,
UInt max_iteration = 100);
/// test if the system is converged
template<SolveConvergenceCriteria criteria>
bool testConvergence(Real tolerance, Real & error);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// time step
Real time_step;
/// conversion coefficient form force/mass to acceleration
Real f_m2a;
/// displacements array
Array<Real> * displacement_rotation;
/// displacements array at the previous time step (used in finite deformation)
Array<Real> * previous_displacement;
/// velocities array
Array<Real> * velocity;
/// accelerations array
Array<Real> * acceleration;
/// forces array
Array<Real> * force_momentum;
/// lumped mass array
Array<Real> * mass;
/// stress arraz
ElementTypeMapArray<Real> stress;
/// residuals array
Array<Real> * residual;
/// boundaries array
Array<bool> * blocked_dofs;
/// position of a dof in the K matrix
Array<Int> * equation_number;
ElementTypeMapArray<UInt> element_material;
// Define sets of beams
ElementTypeMapArray<UInt> set_ID;
/// local equation_number to global
unordered_map<UInt, UInt>::type local_eq_num_to_global;
/// stiffness matrix
SparseMatrix * stiffness_matrix;
/// mass matrix
SparseMatrix * mass_matrix;
/// velocity damping matrix
SparseMatrix * velocity_damping_matrix;
/// jacobian matrix
SparseMatrix * jacobian_matrix;
/// increment of displacement
Array<Real> * increment;
/// solver for implicit
Solver * solver;
/// number of degre of freedom
UInt nb_degree_of_freedom;
// Rotation matrix
ElementTypeMapArray<Real> rotation_matrix;
/// analysis method check the list in akantu::AnalysisMethod
AnalysisMethod method;
/// flag defining if the increment must be computed or not
bool increment_flag;
/// integration scheme of second order used
IntegrationScheme2ndOrder * integrator;
/* -------------------------------------------------------------------------- */
std::vector<StructuralMaterial> materials;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "structural_mechanics_model_inline_impl.cc"
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const StructuralMechanicsModel & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__ */
diff --git a/src/model/structural_mechanics/structural_mechanics_model_boundary.cc b/src/model/structural_mechanics/structural_mechanics_model_boundary.cc
index 59c4ba9ca..f26c941b0 100644
--- a/src/model/structural_mechanics/structural_mechanics_model_boundary.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model_boundary.cc
@@ -1,221 +1,222 @@
/**
* @file structural_mechanics_model_boundary.cc
*
- * @author Damien Spielmann <damien.spielmann@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation: Fri Jul 15 2011
- * @date last modification: Fri Jul 04 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the boundary conditions for StructuralMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "model.hh"
#include "structural_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::transferNMatrixToSymVoigtNMatrix<_bernoulli_beam_2>(Array<Real> & N_matrix) {
AKANTU_DEBUG_IN();
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_nodes_per_element = getFEEngine().getMesh().getNbNodesPerElement(_bernoulli_beam_2);
Array<Real>::const_vector_iterator shape_N0 = fem.getShapeFunctions().getShapes(_bernoulli_beam_2, _not_ghost, 0).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_M0 = fem.getShapeFunctions().getShapes(_bernoulli_beam_2, _not_ghost, 1).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_L0 = fem.getShapeFunctions().getShapes(_bernoulli_beam_2, _not_ghost, 2).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Mp = fem.getShapeFunctions().getShapes(_bernoulli_beam_2, _not_ghost, 3).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Lp = fem.getShapeFunctions().getShapes(_bernoulli_beam_2, _not_ghost, 4).begin(nb_nodes_per_element);
N_matrix.clear();
Array<Real>::matrix_iterator N_it = N_matrix.begin(nb_degree_of_freedom, nb_degree_of_freedom * nb_nodes_per_element);
Array<Real>::matrix_iterator N_end = N_matrix.end(nb_degree_of_freedom, nb_degree_of_freedom * nb_nodes_per_element);
for (;N_it != N_end; ++N_it, ++shape_N0, ++shape_M0, ++shape_L0, ++shape_Mp, ++shape_Lp) {
Matrix<Real> & N = *N_it;
const Vector<Real> & N0 = *shape_N0;
const Vector<Real> & M0 = *shape_M0;
const Vector<Real> & L0 = *shape_L0;
const Vector<Real> & Mp = *shape_Mp;
const Vector<Real> & Lp = *shape_Lp;
N(0,0) = N0(0);
N(0,3) = N0(1);
N(1,1) = M0(0);
N(1,2) = L0(0);
N(1,4) = M0(1);
N(1,5) = L0(1);
N(2,1) = Mp(0);
N(2,2) = Lp(0);
N(2,4) = Mp(1);
N(2,5) = Lp(1);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::transferNMatrixToSymVoigtNMatrix<_bernoulli_beam_3>(Array<Real> & N_matrix) {
AKANTU_DEBUG_IN();
ElementType type = _bernoulli_beam_3;
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_nodes_per_element = getFEEngine().getMesh().getNbNodesPerElement(type);
Array<Real>::const_vector_iterator shape_N0 = fem.getShapeFunctions().getShapes(type, _not_ghost, 0).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_M0 = fem.getShapeFunctions().getShapes(type, _not_ghost, 1).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_L0 = fem.getShapeFunctions().getShapes(type, _not_ghost, 2).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Mp = fem.getShapeFunctions().getShapes(type, _not_ghost, 3).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Lp = fem.getShapeFunctions().getShapes(type, _not_ghost, 4).begin(nb_nodes_per_element);
N_matrix.clear();
Array<Real>::matrix_iterator N_it = N_matrix.begin(nb_degree_of_freedom, nb_degree_of_freedom * nb_nodes_per_element);
Array<Real>::matrix_iterator N_end = N_matrix.end(nb_degree_of_freedom, nb_degree_of_freedom * nb_nodes_per_element);
for (; N_it != N_end; ++N_it, ++shape_N0, ++shape_M0, ++shape_L0, ++shape_Mp, ++shape_Lp) {
Matrix<Real> & N = *N_it;
const Vector<Real> & N0 = *shape_N0;
const Vector<Real> & M0 = *shape_M0;
const Vector<Real> & L0 = *shape_L0;
const Vector<Real> & Mp = *shape_Mp;
const Vector<Real> & Lp = *shape_Lp;
N(0,0) = N0(0);
N(0,6) = N0(1);
N(1,1) = M0(0);
N(1,5) = L0(0);
N(1,7) = M0(1);
N(1,11) = L0(1);
N(2,2) = M0(0);
N(2,4) = -L0(0);
N(2,8) = M0(1);
N(2,10) = -L0(1);
N(3,3) = N0(0);
N(3,9) = N0(1);
N(4,2) = Mp(0);
N(4,4) = -Lp(0);
N(4,8) = Mp(1);
N(4,10) = -Lp(1);
N(5,1) = Mp(0);
N(5,5) = Lp(0);
N(5,7) = Mp(1);
N(5,11) = Lp(1);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::transferNMatrixToSymVoigtNMatrix<_kirchhoff_shell>(Array<Real> & N_matrix) {
AKANTU_DEBUG_IN();
ElementType type = _kirchhoff_shell;
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_nodes_per_element = getFEEngine().getMesh().getNbNodesPerElement(type);
Array<Real>::const_vector_iterator shape_N0 = fem.getShapeFunctions().getShapes(type, _not_ghost, 0).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Nw2 = fem.getShapeFunctions().getShapes(type, _not_ghost, 1).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Nw3 = fem.getShapeFunctions().getShapes(type, _not_ghost, 2).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Nx1 = fem.getShapeFunctions().getShapes(type, _not_ghost, 3).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Nx2 = fem.getShapeFunctions().getShapes(type, _not_ghost, 4).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Nx3 = fem.getShapeFunctions().getShapes(type, _not_ghost, 5).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Ny1 = fem.getShapeFunctions().getShapes(type, _not_ghost, 6).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Ny2 = fem.getShapeFunctions().getShapes(type, _not_ghost, 7).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Ny3 = fem.getShapeFunctions().getShapes(type, _not_ghost, 8).begin(nb_nodes_per_element);
N_matrix.clear();
Array<Real>::matrix_iterator N_it = N_matrix.begin(nb_degree_of_freedom, nb_degree_of_freedom * nb_nodes_per_element);
Array<Real>::matrix_iterator N_end = N_matrix.end(nb_degree_of_freedom, nb_degree_of_freedom * nb_nodes_per_element);
for (; N_it != N_end; ++N_it, ++shape_N0, ++shape_Nw2, ++shape_Nw3, ++shape_Nx1, ++shape_Nx2, ++shape_Nx3, ++shape_Ny1, ++shape_Ny2, ++shape_Ny3) {
Matrix<Real> & N = *N_it;
const Vector<Real> & N0 = *shape_N0;
const Vector<Real> & Nw2 = *shape_Nw2;
const Vector<Real> & Nw3 = *shape_Nw3;
const Vector<Real> & Nx1 = *shape_Nx1;
const Vector<Real> & Nx2 = *shape_Nx2;
const Vector<Real> & Nx3 = *shape_Nx3;
const Vector<Real> & Ny1 = *shape_Ny1;
const Vector<Real> & Ny2 = *shape_Ny2;
const Vector<Real> & Ny3 = *shape_Ny3;
N(0,0) = N0(0);
N(0,5) = N0(1);
N(0,10) = N0(2);
N(1,1) = N0(0);
N(1,5) = N0(1);
N(1,11) = N0(2);
N(2,2) = N0(0);
N(2,3) = Nw2(0);
N(2,4) = Nw3(0);
N(2,7) = N0(1);
N(2,8) = Nw2(1);
N(2,9) = Nw3(1);
N(2,12) = N0(2);
N(2,13) = Nw2(2);
N(2,14) = Nw3(2);
N(3,2) = Nx1(0);
N(3,3) = Nx2(0);
N(3,4) = Nx3(0);
N(3,7) = Nx1(1);
N(3,8) = Nx2(1);
N(3,9) = Nx3(1);
N(3,12) = Nx1(2);
N(3,13) = Nx2(2);
N(3,14) = Nx3(2);
N(4,2) = Ny1(0);
N(4,3) = Ny2(0);
N(4,4) = Ny3(0);
N(4,7) = Ny1(1);
N(4,8) = Ny2(1);
N(4,9) = Ny3(1);
N(4,12) = Ny1(2);
N(4,13) = Ny2(2);
N(4,14) = Ny3(2);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc b/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
index 109cf54aa..f552fa76a 100644
--- a/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
@@ -1,614 +1,615 @@
/**
* @file structural_mechanics_model_inline_impl.cc
*
+ * @author Fabian Barras <fabian.barras@epfl.ch>
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
- * @author Damien Spielmann <damien.spielmann@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation: Fri Jul 15 2011
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Implementation of inline functions of StructuralMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
template<ElementType type>
inline UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize() {
AKANTU_DEBUG_TO_IMPLEMENT();
return 0;
}
template<>
inline UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize<_bernoulli_beam_2>() {
return 2;
}
template<>
inline UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize<_bernoulli_beam_3>() {
return 4;
}
/* -------------------------------------------------------------------------- */
template<>
inline UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize<_kirchhoff_shell>() {
return 6;
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
void StructuralMechanicsModel::assembleStiffnessMatrix() {
AKANTU_DEBUG_IN();
SparseMatrix & K = *stiffness_matrix;
UInt nb_element = getFEEngine().getMesh().getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
UInt tangent_size = getTangentStiffnessVoigtSize<type>();
Array<Real> * tangent_moduli =
new Array<Real>(nb_element * nb_quadrature_points, tangent_size * tangent_size,
"tangent_stiffness_matrix");
tangent_moduli->clear();
computeTangentModuli<type>(*tangent_moduli);
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_d_b_size = nb_degree_of_freedom * nb_nodes_per_element;
Array<Real> * bt_d_b = new Array<Real>(nb_element*nb_quadrature_points,
bt_d_b_size * bt_d_b_size,
"B^t*D*B");
Array<Real> * b = new Array<Real>(nb_element*nb_quadrature_points,
tangent_size*bt_d_b_size,
"B");
transferBMatrixToSymVoigtBMatrix<type>(*b);
Matrix<Real> Bt_D(bt_d_b_size, tangent_size);
Matrix<Real> BT(tangent_size, bt_d_b_size);
Array<Real>::matrix_iterator B = b->begin(tangent_size, bt_d_b_size);
Array<Real>::matrix_iterator D = tangent_moduli->begin(tangent_size, tangent_size);
Array<Real>::matrix_iterator Bt_D_B = bt_d_b->begin(bt_d_b_size, bt_d_b_size);
Array<Real>::matrix_iterator T = rotation_matrix(type).begin(bt_d_b_size, bt_d_b_size);
for (UInt e = 0; e < nb_element; ++e, ++T) {
for (UInt q = 0; q < nb_quadrature_points; ++q, ++B, ++D, ++Bt_D_B) {
BT.mul<false, false>(*B, *T);
Bt_D.mul<true, false>(BT, *D);
Bt_D_B->mul<false, false>(Bt_D, BT);
}
}
delete b;
delete tangent_moduli;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * int_bt_d_b = new Array<Real>(nb_element,
bt_d_b_size * bt_d_b_size,
"int_B^t*D*B");
getFEEngine().integrate(*bt_d_b, *int_bt_d_b,
bt_d_b_size * bt_d_b_size,
type);
delete bt_d_b;
getFEEngine().assembleMatrix(*int_bt_d_b, K, nb_degree_of_freedom, type);
delete int_bt_d_b;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<ElementType type>
void StructuralMechanicsModel::computeTangentModuli(Array<Real> & tangent_moduli) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template<ElementType type>
void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix(Array<Real> & b, bool local) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template<ElementType type>
void StructuralMechanicsModel::computeStressOnQuad() {
AKANTU_DEBUG_IN();
Array<Real> & sigma = stress(type, _not_ghost);
sigma.clear();
const Mesh & mesh = getFEEngine().getMesh();
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
UInt tangent_size = getTangentStiffnessVoigtSize<type>();
Array<Real> * tangent_moduli =
new Array<Real>(nb_element*nb_quadrature_points, tangent_size * tangent_size,
"tangent_stiffness_matrix");
tangent_moduli->clear();
computeTangentModuli<type>(*tangent_moduli);
/// compute DB
UInt d_b_size = nb_degree_of_freedom * nb_nodes_per_element;
Array<Real> * d_b = new Array<Real>(nb_element*nb_quadrature_points,
d_b_size * tangent_size,
"D*B");
Array<Real> * b = new Array<Real>(nb_element*nb_quadrature_points,
tangent_size*d_b_size,
"B");
transferBMatrixToSymVoigtBMatrix<type>(*b);
Array<Real>::matrix_iterator B = b->begin(tangent_size, d_b_size);
Array<Real>::matrix_iterator D = tangent_moduli->begin(tangent_size, tangent_size);
Array<Real>::matrix_iterator D_B = d_b->begin(tangent_size, d_b_size);
for (UInt e = 0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quadrature_points; ++q, ++B, ++D, ++D_B) {
D_B->mul<false, false>(*D, *B);
}
}
delete b;
delete tangent_moduli;
/// compute DBu
D_B = d_b->begin(tangent_size, d_b_size);
Array<Real>::iterator< Vector<Real> > DBu = sigma.begin(tangent_size);
Vector<Real> ul (d_b_size);
Array<Real> u_el(0, d_b_size);
FEEngine::extractNodalToElementField(mesh, *displacement_rotation, u_el, type);
Array<Real>::vector_iterator ug = u_el.begin(d_b_size);
Array<Real>::matrix_iterator T = rotation_matrix(type).begin(d_b_size, d_b_size);
for (UInt e = 0; e < nb_element; ++e, ++T, ++ug) {
ul.mul<false>(*T, *ug);
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_B, ++DBu) {
DBu->mul<false>(*D_B, ul);
}
}
delete d_b;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<ElementType type>
void StructuralMechanicsModel::computeForcesByLocalTractionArray(const Array<Real> & tractions) {
AKANTU_DEBUG_IN();
UInt nb_element = getFEEngine().getMesh().getNbElement(type);
UInt nb_nodes_per_element = getFEEngine().getMesh().getNbNodesPerElement(type);
UInt nb_quad = getFEEngine().getNbIntegrationPoints(type);
// check dimension match
AKANTU_DEBUG_ASSERT(Mesh::getSpatialDimension(type) == getFEEngine().getElementDimension(),
"element type dimension does not match the dimension of boundaries : " <<
getFEEngine().getElementDimension() << " != " <<
Mesh::getSpatialDimension(type));
// check size of the vector
AKANTU_DEBUG_ASSERT(tractions.getSize() == nb_quad*nb_element,
"the size of the vector should be the total number of quadrature points");
// check number of components
AKANTU_DEBUG_ASSERT(tractions.getNbComponent() == nb_degree_of_freedom,
"the number of components should be the spatial dimension of the problem");
Array<Real> Nvoigt(nb_element * nb_quad, nb_degree_of_freedom * nb_degree_of_freedom * nb_nodes_per_element);
transferNMatrixToSymVoigtNMatrix<type>(Nvoigt);
Array<Real>::const_matrix_iterator N_it = Nvoigt.begin(nb_degree_of_freedom,
nb_degree_of_freedom * nb_nodes_per_element);
Array<Real>::const_matrix_iterator T_it = rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element,
nb_degree_of_freedom * nb_nodes_per_element);
Array<Real>::const_vector_iterator te_it = tractions.begin(nb_degree_of_freedom);
Array<Real> funct(nb_element * nb_quad, nb_degree_of_freedom * nb_nodes_per_element, 0.);
Array<Real>::iterator< Vector<Real> > Fe_it = funct.begin(nb_degree_of_freedom * nb_nodes_per_element);
Vector<Real> fe(nb_degree_of_freedom * nb_nodes_per_element);
for (UInt e = 0; e < nb_element; ++e, ++T_it) {
const Matrix<Real> & T = *T_it;
for (UInt q = 0; q < nb_quad; ++q, ++N_it, ++te_it, ++Fe_it) {
const Matrix<Real> & N = *N_it;
const Vector<Real> & te = *te_it;
Vector<Real> & Fe = *Fe_it;
// compute N^t tl
fe.mul<true>(N, te);
// turn N^t tl back in the global referential
Fe.mul<true>(T, fe);
}
}
// allocate the vector that will contain the integrated values
std::stringstream name;
name << id << type << ":integral_boundary";
Array<Real> int_funct(nb_element, nb_degree_of_freedom * nb_nodes_per_element, name.str());
//do the integration
getFEEngine().integrate(funct, int_funct, nb_degree_of_freedom*nb_nodes_per_element, type);
// assemble the result into force vector
getFEEngine().assembleArray(int_funct,*force_momentum,
dof_synchronizer->getLocalDOFEquationNumbers(),
nb_degree_of_freedom, type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<ElementType type>
void StructuralMechanicsModel::computeForcesByGlobalTractionArray(const Array<Real> & traction_global){
AKANTU_DEBUG_IN();
UInt nb_element = getFEEngine().getMesh().getNbElement(type);
UInt nb_quad = getFEEngine().getNbIntegrationPoints(type);
UInt nb_nodes_per_element = getFEEngine().getMesh().getNbNodesPerElement(type);
std::stringstream name;
name << id << ":structuralmechanics:imposed_linear_load";
Array<Real> traction_local(nb_element*nb_quad, nb_degree_of_freedom, name.str());
Array<Real>::const_matrix_iterator T_it = rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element,
nb_degree_of_freedom * nb_nodes_per_element);
Array<Real>::const_iterator< Vector<Real> > Te_it = traction_global.begin(nb_degree_of_freedom);
Array<Real>::iterator< Vector<Real> > te_it = traction_local.begin(nb_degree_of_freedom);
Matrix<Real> R(nb_degree_of_freedom, nb_degree_of_freedom);
for (UInt e = 0; e < nb_element; ++e, ++T_it) {
const Matrix<Real> & T = *T_it;
for (UInt i = 0; i < nb_degree_of_freedom; ++i)
for (UInt j = 0; j < nb_degree_of_freedom; ++j)
R(i, j) = T(i, j);
for (UInt q = 0; q < nb_quad; ++q, ++Te_it, ++te_it) {
const Vector<Real> & Te = *Te_it;
Vector<Real> & te = *te_it;
// turn the traction in the local referential
te.mul<false>(R, Te);
}
}
computeForcesByLocalTractionArray<type>(traction_local);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* @param myf pointer to a function that fills a vector/tensor with respect to
* passed coordinates
*/
template<ElementType type>
inline void StructuralMechanicsModel::computeForcesFromFunction(BoundaryFunction myf,
BoundaryFunctionType function_type){
/** function type is
** _bft_forces : linear load is given
** _bft_stress : stress function is given -> Not already done for this kind of model
*/
std::stringstream name;
name << id << ":structuralmechanics:imposed_linear_load";
Array<Real> lin_load(0, nb_degree_of_freedom,name.str());
name.clear();
UInt offset = nb_degree_of_freedom;
//prepare the loop over element types
UInt nb_quad = getFEEngine().getNbIntegrationPoints(type);
UInt nb_element = getFEEngine().getMesh().getNbElement(type);
name.clear();
name << id << ":structuralmechanics:quad_coords";
Array<Real> quad_coords(nb_element * nb_quad, spatial_dimension, "quad_coords");
getFEEngineClass<MyFEEngineType>().getShapeFunctions().interpolateOnIntegrationPoints<type>(getFEEngine().getMesh().getNodes(),
quad_coords,
spatial_dimension);
getFEEngineClass<MyFEEngineType>().getShapeFunctions().interpolateOnIntegrationPoints<type>(getFEEngine().getMesh().getNodes(),
quad_coords,
spatial_dimension,
_not_ghost,
empty_filter,
true,
0,
1,
1);
if(spatial_dimension == 3)
getFEEngineClass<MyFEEngineType>().getShapeFunctions().interpolateOnIntegrationPoints<type>(getFEEngine().getMesh().getNodes(),
quad_coords,
spatial_dimension,
_not_ghost,
empty_filter,
true,
0,
2,
2);
lin_load.resize(nb_element*nb_quad);
Real * imposed_val = lin_load.storage();
/// sigma/load on each quadrature points
Real * qcoord = quad_coords.storage();
for (UInt el = 0; el < nb_element; ++el) {
for (UInt q = 0; q < nb_quad; ++q) {
myf(qcoord, imposed_val, NULL, 0);
imposed_val += offset;
qcoord += spatial_dimension;
}
}
switch(function_type) {
case _bft_traction_local:
computeForcesByLocalTractionArray<type>(lin_load); break;
case _bft_traction:
computeForcesByGlobalTractionArray<type>(lin_load); break;
default: break;
}
}
/* -------------------------------------------------------------------------- */
template<>
inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_2>() {
AKANTU_DEBUG_IN();
GhostType ghost_type = _not_ghost;
ElementType type = _bernoulli_beam_2;
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_element = getFEEngine().getMesh().getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
UInt nb_fields_to_interpolate = getTangentStiffnessVoigtSize<_bernoulli_beam_2>();
UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
Array<Real> * n = new Array<Real>(nb_element*nb_quadrature_points,
nb_fields_to_interpolate * nt_n_field_size,
"N");
n->clear();
Array<Real> * rho_field = new Array<Real>(nb_element*nb_quadrature_points,
"Rho");
rho_field->clear();
computeRho(*rho_field, type, _not_ghost);
bool sign = true;
/* -------------------------------------------------------------------------- */
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 0, 0, 0, sign, ghost_type); // Ni ui -> u
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 1, 1, 1, sign, ghost_type); // Mi vi -> v
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 2, 2, 1, sign, ghost_type); // Li Theta_i -> v
/* -------------------------------------------------------------------------- */
fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n, rotation_matrix, type, ghost_type);
delete n;
delete rho_field;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_3>() {
AKANTU_DEBUG_IN();
GhostType ghost_type = _not_ghost;
ElementType type = _bernoulli_beam_3;
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_element = getFEEngine().getMesh().getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
UInt nb_fields_to_interpolate = getTangentStiffnessVoigtSize<_bernoulli_beam_3>();
UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
Array<Real> * n = new Array<Real>(nb_element*nb_quadrature_points,
nb_fields_to_interpolate * nt_n_field_size,
"N");
n->clear();
Array<Real> * rho_field = new Array<Real>(nb_element * nb_quadrature_points,
"Rho");
rho_field->clear();
computeRho(*rho_field, type, _not_ghost);
/* -------------------------------------------------------------------------- */
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 0, 0, 0, true, ghost_type); // Ni ui -> u
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 1, 1, 1, true, ghost_type); // Mi vi -> v
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 2, 5, 1, true, ghost_type); // Li Theta_z_i -> v
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 1, 2, 2, true, ghost_type); // Mi wi -> w
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 2, 4, 2, false,ghost_type);// -Li Theta_y_i -> w
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 0, 3, 3, true, ghost_type); // Ni Theta_x_i->Theta_x
/* -------------------------------------------------------------------------- */
fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n, rotation_matrix, type, ghost_type);
delete n;
delete rho_field;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
inline void StructuralMechanicsModel::assembleMass<_kirchhoff_shell>() {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool StructuralMechanicsModel::solveStep(Real tolerance,
UInt max_iteration) {
Real error = 0.;
return this->template solveStep<cmethod,criteria>(tolerance,
error,
max_iteration);
}
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool StructuralMechanicsModel::solveStep(Real tolerance, Real & error, UInt max_iteration) {
this->implicitPred();
this->updateResidual();
AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
"You should first initialize the implicit solver and assemble the stiffness matrix");
if (method==_implicit_dynamic) {
AKANTU_DEBUG_ASSERT(mass_matrix != NULL,
"You should first initialize the implicit solver and assemble the mass matrix");
}
switch (cmethod) {
case _scm_newton_raphson_tangent:
case _scm_newton_raphson_tangent_not_computed:
break;
case _scm_newton_raphson_tangent_modified:
this->assembleStiffnessMatrix();
break;
default:
AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
}
UInt iter = 0;
bool converged = false;
error = 0.;
if(criteria == _scc_residual) {
converged = this->testConvergence<criteria> (tolerance, error);
if(converged) return converged;
}
do {
if (cmethod == _scm_newton_raphson_tangent)
this->assembleStiffnessMatrix();
solve<NewmarkBeta::_displacement_corrector> (*increment);
this->implicitCorr();
if(criteria == _scc_residual) this->updateResidual();
converged = this->testConvergence<criteria> (tolerance, error);
if(criteria == _scc_increment && !converged) this->updateResidual();
//this->dump();
iter++;
AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration "
<< std::setw(std::log10(max_iteration)) << iter
<< ": error " << error << (converged ? " < " : " > ") << tolerance);
} while (!converged && iter < max_iteration);
if (converged) {
} else if(iter == max_iteration) {
AKANTU_DEBUG_WARNING("[" << criteria << "] Convergence not reached after "
<< std::setw(std::log10(max_iteration)) << iter <<
" iteration" << (iter == 1 ? "" : "s") << "!" << std::endl);
}
return converged;
}
/* -------------------------------------------------------------------------- */
template<NewmarkBeta::IntegrationSchemeCorrectorType type>
void StructuralMechanicsModel::solve(Array<Real> & increment,
Real block_val) {
jacobian_matrix->clear();
//updateResidualInternal(); //doesn't do anything for static
Real c = 0.,d = 0.,e = 0.;
if(method == _static) {
AKANTU_DEBUG_INFO("Solving K inc = r");
e = 1.;
} else {
AKANTU_DEBUG_INFO("Solving (c M + d C + e K) inc = r");
NewmarkBeta * nmb_int = dynamic_cast<NewmarkBeta *>(integrator);
c = nmb_int->getAccelerationCoefficient<type>(time_step);
d = nmb_int->getVelocityCoefficient<type>(time_step);
e = nmb_int->getDisplacementCoefficient<type>(time_step);
}
// J = c M + d C + e K
if(stiffness_matrix)
jacobian_matrix->add(*stiffness_matrix, e);
// if(type != NewmarkBeta::_acceleration_corrector)
// jacobian_matrix->add(*stiffness_matrix, e);
if(mass_matrix)
jacobian_matrix->add(*mass_matrix, c);
#if !defined(AKANTU_NDEBUG)
if(mass_matrix && AKANTU_DEBUG_TEST(dblDump))
mass_matrix->saveMatrix("M.mtx");
#endif
if(velocity_damping_matrix)
jacobian_matrix->add(*velocity_damping_matrix, d);
jacobian_matrix->applyBoundary(*blocked_dofs);
#if !defined(AKANTU_NDEBUG)
if(AKANTU_DEBUG_TEST(dblDump))
jacobian_matrix->saveMatrix("J.mtx");
#endif
solver->setRHS(*residual);
// solve @f[ J \delta w = r @f]
solver->factorize();
solver->solve(increment);
}
diff --git a/src/model/structural_mechanics/structural_mechanics_model_mass.cc b/src/model/structural_mechanics/structural_mechanics_model_mass.cc
index 30d2152a5..f9643aabc 100644
--- a/src/model/structural_mechanics/structural_mechanics_model_mass.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model_mass.cc
@@ -1,100 +1,100 @@
/**
* @file structural_mechanics_model_mass.cc
*
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
*
* @date creation: Mon Jul 07 2014
- * @date last modification: Mon Jul 07 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief function handling mass computation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
-/* -------------------------------------------------------------------------- */
-
-#include "structural_mechanics_model.hh"
-#include "material.hh"
-/* -------------------------------------------------------------------------- */
-
-__BEGIN_AKANTU__
-
-/* -------------------------------------------------------------------------- */
-
-void StructuralMechanicsModel::assembleMass(){
- AKANTU_DEBUG_IN();
-
- if(!mass_matrix){
- std::stringstream sstr; sstr << id << ":mass_matrix";
- mass_matrix = new SparseMatrix(*jacobian_matrix, sstr.str(), memory_id);
- }
-
- assembleMass(_not_ghost);
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void StructuralMechanicsModel::assembleMass(GhostType ghost_type) {
- AKANTU_DEBUG_IN();
-
- Array<Real> rho_1(0,1);
- mass_matrix->clear();
-
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_structural);
- Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type, _ek_structural);
- for(; it != end; ++it){
- ElementType type = *it;
-
-#define ASSEMBLE_MASS(type) \
- assembleMass<type>();
-
- AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(ASSEMBLE_MASS);
-#undef ASSEMBLE_MASS
-
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-
-void StructuralMechanicsModel::computeRho(Array<Real> & rho,
- ElementType type,
- GhostType ghost_type) {
- AKANTU_DEBUG_IN();
-
- UInt nb_element = getFEEngine().getMesh().getNbElement(type);
- UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
-
- Array<UInt> & el_mat = element_material(type, ghost_type);
-
- for (UInt e = 0; e < nb_element; ++e){
- UInt mat = el_mat(e);
- Real rho_el = materials[mat].rho;
- for (UInt q = e*nb_quadrature_points; q < e*nb_quadrature_points + nb_quadrature_points; ++q){
- rho(q) = rho_el;
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-__END_AKANTU__
+/* -------------------------------------------------------------------------- */
+
+#include "structural_mechanics_model.hh"
+#include "material.hh"
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+
+void StructuralMechanicsModel::assembleMass(){
+ AKANTU_DEBUG_IN();
+
+ if(!mass_matrix){
+ std::stringstream sstr; sstr << id << ":mass_matrix";
+ mass_matrix = new SparseMatrix(*jacobian_matrix, sstr.str(), memory_id);
+ }
+
+ assembleMass(_not_ghost);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void StructuralMechanicsModel::assembleMass(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Array<Real> rho_1(0,1);
+ mass_matrix->clear();
+
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_structural);
+ Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type, _ek_structural);
+ for(; it != end; ++it){
+ ElementType type = *it;
+
+#define ASSEMBLE_MASS(type) \
+ assembleMass<type>();
+
+ AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(ASSEMBLE_MASS);
+#undef ASSEMBLE_MASS
+
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+void StructuralMechanicsModel::computeRho(Array<Real> & rho,
+ ElementType type,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_element = getFEEngine().getMesh().getNbElement(type);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
+
+ Array<UInt> & el_mat = element_material(type, ghost_type);
+
+ for (UInt e = 0; e < nb_element; ++e){
+ UInt mat = el_mat(e);
+ Real rho_el = materials[mat].rho;
+ for (UInt q = e*nb_quadrature_points; q < e*nb_quadrature_points + nb_quadrature_points; ++q){
+ rho(q) = rho_el;
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/src/python/python_functor.cc b/src/python/python_functor.cc
index 9e82870ca..61278c0bd 100644
--- a/src/python/python_functor.cc
+++ b/src/python/python_functor.cc
@@ -1,76 +1,79 @@
/**
* @file python_functor.cc
*
-
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Fri Nov 13 2015
+ *
+ * @brief Python functor interface
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "python_functor.hh"
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
PythonFunctor::PythonFunctor(PyObject * obj):python_obj(obj){
}
/* -------------------------------------------------------------------------- */
PyObject * PythonFunctor::callFunctor(PyObject * functor,
PyObject * args,
PyObject * kwargs) const{
if (!PyCallable_Check(functor))
AKANTU_EXCEPTION("Provided functor is not a function");
PyObject * pValue = PyObject_Call(functor, args,kwargs);
PyObject* exception_type = PyErr_Occurred();
if (exception_type){
PyObject * exception;
PyObject * traceback;
PyErr_Fetch(&exception_type, &exception, &traceback);
PyObject_Print(exception_type, stdout, Py_PRINT_RAW);
PyObject_Print(exception, stdout, Py_PRINT_RAW);
std::stringstream sstr;
sstr << "Exception occured while calling the functor: ";
PyObject * exception_mesg = PyObject_GetAttrString(exception,"message");
if (exception_mesg && PyString_Check(exception_mesg))
sstr << PyString_AsString(exception_mesg);
else
sstr << PyString_AsString(exception);
AKANTU_EXCEPTION(sstr.str());
}
return pValue;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/python/python_functor.hh b/src/python/python_functor.hh
index 5237cef37..0cf981e24 100644
--- a/src/python/python_functor.hh
+++ b/src/python/python_functor.hh
@@ -1,124 +1,127 @@
/**
* @file python_functor.hh
*
-
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Nov 15 2015
+ *
+ * @brief Python Functor interface
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
-
#ifndef __AKANTU_PYTHON_FUNCTOR_HH__
#define __AKANTU_PYTHON_FUNCTOR_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include <Python.h>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class PythonFunctor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PythonFunctor(PyObject * obj);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
/// call the python functor
PyObject * callFunctor(PyObject * functor,
PyObject * args,
PyObject * kwargs) const;
/// call the python functor from variadic types
template <typename return_type, typename... Params>
return_type callFunctor(const std::string & functor_name,
Params&... parameters) const;
/// empty function to cose the recursive template loop
inline void packArguments(std::vector<PyObject*> & pArgs) const;
/// get the python function object
inline PyObject * getPythonFunction(const std::string & functor_name) const;
/// variadic template for unknown number of arguments to unpack
template<typename T, typename... Args>
inline void packArguments(std::vector<PyObject*> & pArgs,
T & p,
Args&...params) const;
/// convert an akantu object to python
template <typename T>
inline PyObject *convertToPython(const T & akantu_obj) const;
/// convert a stl vector to python
template <typename T>
inline PyObject *convertToPython(const std::vector<T> & akantu_obj) const;
/// convert an akantu vector to python
template <typename T>
inline PyObject *convertToPython(const Vector<T> & akantu_obj) const;
/// convert a akantu matrix to python
template <typename T>
inline PyObject *convertToPython(const Matrix<T> & akantu_obj) const;
/// convert a python object to an akantu object
template <typename return_type>
inline return_type convertToAkantu(PyObject * python_obj) const;
/// convert a python object to an akantu object
template <typename T>
inline std::vector<T> convertListToAkantu(PyObject * python_obj) const;
/// returns the numpy data type code
template <typename T>
inline int getPythonDataTypeCode() const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
PyObject * python_obj;
};
/* -------------------------------------------------------------------------- */
__END_AKANTU__
/* -------------------------------------------------------------------------- */
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "python_functor_inline_impl.cc"
/* -------------------------------------------------------------------------- */
#endif /* __AKANTU_PYTHON_FUNCTOR_HH__ */
diff --git a/src/python/python_functor_inline_impl.cc b/src/python/python_functor_inline_impl.cc
index bd51e5f4c..c02c481e7 100644
--- a/src/python/python_functor_inline_impl.cc
+++ b/src/python/python_functor_inline_impl.cc
@@ -1,244 +1,274 @@
+/**
+ * @file python_functor_inline_impl.cc
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ *
+ * @date creation: Fri Nov 13 2015
+ * @date last modification: Wed Nov 18 2015
+ *
+ * @brief Python functor interface
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
#ifndef __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
#define __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
/* -------------------------------------------------------------------------- */
#include <numpy/arrayobject.h>
#include "integration_point.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <typename T>
inline int PythonFunctor::getPythonDataTypeCode() const{
AKANTU_EXCEPTION("undefined type");
}
/* -------------------------------------------------------------------------- */
template <>
inline int PythonFunctor::getPythonDataTypeCode<bool>() const{
int data_typecode = NPY_NOTYPE;
size_t s = sizeof(bool);
switch(s) {
case 1: data_typecode = NPY_BOOL; break;
case 2: data_typecode = NPY_UINT16; break;
case 4: data_typecode = NPY_UINT32; break;
case 8: data_typecode = NPY_UINT64; break;
}
return data_typecode;
}
/* -------------------------------------------------------------------------- */
template <>
inline int PythonFunctor::getPythonDataTypeCode<double>() const{
return NPY_DOUBLE;
}
/* -------------------------------------------------------------------------- */
template <typename T>
PyObject *PythonFunctor::convertToPython(const T & akantu_object) const{
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *PythonFunctor::convertToPython<double>(const double & akantu_object) const{
return PyFloat_FromDouble(akantu_object);
}
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *PythonFunctor::convertToPython<UInt>(const UInt & akantu_object) const{
return PyInt_FromLong(akantu_object);
}
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *PythonFunctor::convertToPython<bool>(const bool & akantu_object) const{
return PyBool_FromLong(long(akantu_object));
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline PyObject *PythonFunctor::convertToPython(const std::vector<T> & array) const{
int data_typecode = getPythonDataTypeCode< T >();
npy_intp dims[1] = {int(array.size())};
PyObject* obj = PyArray_SimpleNewFromData(1, dims, data_typecode, const_cast<T*>(&array[0]));
PyArrayObject* res = (PyArrayObject*) obj;
return (PyObject*)res;
}
/* -------------------------------------------------------------------------- */
template <typename T>
PyObject *PythonFunctor::convertToPython(const Vector<T> & array) const{
int data_typecode = getPythonDataTypeCode< T >();
npy_intp dims[1] = {array.size()};
PyObject* obj = PyArray_SimpleNewFromData(1, dims, data_typecode, array.storage());
PyArrayObject* res = (PyArrayObject*) obj;
return (PyObject*)res;
}
/* -------------------------------------------------------------------------- */
template <typename T>
PyObject *PythonFunctor::convertToPython(const Matrix<T> & mat) const{
int data_typecode = getPythonDataTypeCode< T >();
npy_intp dims[2] = {mat.size(0),mat.size(1)};
PyObject* obj = PyArray_SimpleNewFromData(2, dims, data_typecode, mat.storage());
PyArrayObject* res = (PyArrayObject*) obj;
return (PyObject*)res;
}
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *PythonFunctor::convertToPython<std::string>(const std::string & str) const{
return PyString_FromString(str.c_str());
}
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *PythonFunctor::convertToPython<IntegrationPoint>(const IntegrationPoint & qp) const{
PyObject * input = PyDict_New();
PyObject * num_point = this->convertToPython(qp.num_point);
PyObject * global_num = this->convertToPython(qp.global_num);
PyObject * material_id = this->convertToPython(qp.material_id);
PyObject * position = this->convertToPython(qp.getPosition());
PyDict_SetItemString(input,"num_point",num_point);
PyDict_SetItemString(input,"global_num",global_num);
PyDict_SetItemString(input,"material_id",material_id);
PyDict_SetItemString(input,"position",position);
return input;
}
/* -------------------------------------------------------------------------- */
inline PyObject * PythonFunctor::getPythonFunction(const std::string & functor_name) const{
if (!PyInstance_Check(this->python_obj))
AKANTU_EXCEPTION("Python object is not an instance");
// if (!PyDict_Check(this->python_obj))
// AKANTU_EXCEPTION("Python object is not a dictionary");
//PyObject * keys = PyDict_Keys(dict);
//PyObject_Print(keys, stdout, Py_PRINT_RAW);
PyObject * pFunctor = PyObject_GetAttrString(this->python_obj, functor_name.c_str());
if (!pFunctor) AKANTU_EXCEPTION("Python dictionary has no " << functor_name << " entry");
return pFunctor;
}
/* -------------------------------------------------------------------------- */
inline void PythonFunctor::packArguments(std::vector<PyObject*> & pArgs)const {}
/* -------------------------------------------------------------------------- */
template<typename T, typename... Args>
inline void PythonFunctor::packArguments(std::vector<PyObject*> & pArgs,
T & p,
Args&...params)const{
pArgs.push_back(this->convertToPython(p));
if (sizeof...(params) != 0)
this->packArguments(pArgs,params...);
}
/* -------------------------------------------------------------------------- */
template <typename return_type, typename... Params>
return_type PythonFunctor::callFunctor(const std::string & functor_name,
Params&... parameters) const{
_import_array();
std::vector<PyObject*> arg_vector;
this->packArguments(arg_vector,parameters...);
PyObject * pArgs = PyTuple_New(arg_vector.size());
for (UInt i = 0; i < arg_vector.size(); ++i) {
PyTuple_SetItem(pArgs,i,arg_vector[i]);
}
PyObject * kwargs = PyDict_New();
PyObject * pFunctor = getPythonFunction(functor_name);
PyObject * res = this->callFunctor(pFunctor,pArgs,kwargs);
// for (auto a: arg_vector) {
// // if (PyDict_Check(a)){
// // PyObject* values = PyDict_Values(a);
// // UInt sz = PyList_GET_SIZE(values);
// // for (UInt i = 0; i < sz; ++i) {
// // Py_XDECREF(PyList_GetItem(values,i));
// // }
// // }
// // Py_XDECREF(a);
// }
Py_XDECREF(pArgs);
Py_XDECREF(kwargs);
return this->convertToAkantu<return_type>(res);
}
/* -------------------------------------------------------------------------- */
template <typename return_type>
inline return_type PythonFunctor::convertToAkantu(PyObject * python_obj) const{
if (PyList_Check(python_obj)){
return this->convertListToAkantu<typename return_type::value_type>(python_obj);
}
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template <>
inline void PythonFunctor::convertToAkantu<void>(PyObject * python_obj) const{
if (python_obj != Py_None) AKANTU_DEBUG_WARNING("functor return a value while none was expected: ignored");
}
/* -------------------------------------------------------------------------- */
template <>
inline std::string PythonFunctor::convertToAkantu<std::string>(PyObject * python_obj) const{
if (!PyString_Check(python_obj)) AKANTU_EXCEPTION("cannot convert object to string");
return PyString_AsString(python_obj);
}
/* -------------------------------------------------------------------------- */
template <>
inline Real PythonFunctor::convertToAkantu<Real>(PyObject * python_obj) const{
if (!PyFloat_Check(python_obj)) AKANTU_EXCEPTION("cannot convert object to float");
return PyFloat_AsDouble(python_obj);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline std::vector<T> PythonFunctor::convertListToAkantu(PyObject * python_obj) const{
std::vector<T> res;
UInt size = PyList_Size(python_obj);
for (UInt i = 0; i < size; ++i) {
PyObject * item = PyList_GET_ITEM(python_obj,i);
res.push_back(this->convertToAkantu<T>(item));
}
return res;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__ */
diff --git a/src/solver/petsc_matrix.cc b/src/solver/petsc_matrix.cc
index d6b7a9be5..3d9ef8414 100644
--- a/src/solver/petsc_matrix.cc
+++ b/src/solver/petsc_matrix.cc
@@ -1,643 +1,647 @@
/**
* @file petsc_matrix.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Mon Jul 21 17:40:41 2014
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Mon Dec 13 2010
+ * @date last modification: Fri Aug 21 2015
*
* @brief Implementation of PETSc matrix class
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "petsc_matrix.hh"
#include "static_communicator.hh"
#include "static_communicator_mpi.hh"
#include "mpi_type_wrapper.hh"
#include "dof_synchronizer.hh"
#include "petsc_wrapper.hh"
/* -------------------------------------------------------------------------- */
#include <cstring>
#include <petscsys.h>
__BEGIN_AKANTU__
#if not defined(PETSC_CLANGUAGE_CXX)
int aka_PETScError(int ierr) {
CHKERRQ(ierr);
return 0;
}
#endif
// struct PETScWrapper {
// Mat mat;
// AO ao;
// ISLocalToGlobalMapping mapping;
// /// pointer to the MPI communicator for PETSc commands
// MPI_Comm communicator;
// };
/* -------------------------------------------------------------------------- */
PETScMatrix::PETScMatrix(UInt size,
const SparseMatrixType & sparse_matrix_type,
const ID & id,
const MemoryID & memory_id) :
SparseMatrix(size, sparse_matrix_type, id, memory_id),
petsc_matrix_wrapper(new PETScMatrixWrapper),
d_nnz(0,1,"dnnz"),
o_nnz(0,1,"onnz"),
first_global_index(0),
is_petsc_matrix_initialized(false) {
AKANTU_DEBUG_IN();
StaticSolver::getStaticSolver().registerEventHandler(*this);
this->offset = 0;
this->init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
PETScMatrix::PETScMatrix(const SparseMatrix & matrix,
const ID & id,
const MemoryID & memory_id) :
SparseMatrix(matrix, id, memory_id),
petsc_matrix_wrapper(new PETScMatrixWrapper),
d_nnz(0,1,"dnnz"),
o_nnz(0,1,"onnz"),
first_global_index(0),
is_petsc_matrix_initialized(false) {
// AKANTU_DEBUG_IN();
// StaticSolver::getStaticSolver().registerEventHandler(*this);
// this->offset = 0;
// this->init();
// AKANTU_DEBUG_OUT();
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
PETScMatrix::~PETScMatrix() {
AKANTU_DEBUG_IN();
/// destroy all the PETSc data structures used for this matrix
this->destroyInternalData();
StaticSolver::getStaticSolver().unregisterEventHandler(*this);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void PETScMatrix::init() {
AKANTU_DEBUG_IN();
/// set the communicator that should be used by PETSc
#if defined(AKANTU_USE_MPI)
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
const StaticCommunicatorMPI & mpi_st_comm =
dynamic_cast<const StaticCommunicatorMPI &>(comm.getRealStaticCommunicator());
this->petsc_matrix_wrapper->communicator = mpi_st_comm.getMPITypeWrapper().getMPICommunicator();
#else
this->petsc_matrix_wrapper->communicator = PETSC_COMM_SELF;
#endif
PetscErrorCode ierr;
/// create the PETSc matrix object
ierr = MatCreate(this->petsc_matrix_wrapper->communicator, &(this->petsc_matrix_wrapper->mat)); CHKERRXX(ierr);
/**
* Set the matrix type
* @todo PETSc does currently not support a straightforward way to
* apply Dirichlet boundary conditions for MPISBAIJ
* matrices. Therefore always the entire matrix is allocated. It
* would be possible to use MATSBAIJ for sequential matrices in case
* memory becomes critical. Also, block matrices would give a much
* better performance. Modify this in the future!
*/
ierr = MatSetType(this->petsc_matrix_wrapper->mat, MATAIJ); CHKERRXX(ierr);
this->is_petsc_matrix_initialized = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* With this method each processor computes the dimensions of the
* local matrix, i.e. the part of the global matrix it is storing.
* @param dof_synchronizer dof synchronizer that maps the local
* dofs to the global dofs and the equation numbers, i.e., the
* position at which the dof is assembled in the matrix
*/
void PETScMatrix::setSize() {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
/// find the number of dofs corresponding to master or local nodes
UInt nb_dofs = this->dof_synchronizer->getNbDOFs();
UInt nb_local_master_dofs = 0;
/// create array to store the global equation number of all local and master dofs
Array<Int> local_master_eq_nbs(nb_dofs);
Array<Int>::scalar_iterator it_eq_nb = local_master_eq_nbs.begin();
/// get the pointer to the global equation number array
Int * eq_nb_val = this->dof_synchronizer->getGlobalDOFEquationNumbers().storage();
for (UInt i = 0; i <nb_dofs; ++i) {
if (this->dof_synchronizer->isLocalOrMasterDOF(i) ) {
*it_eq_nb = eq_nb_val[i];
++it_eq_nb;
++nb_local_master_dofs;
}
}
local_master_eq_nbs.resize(nb_local_master_dofs);
/// set the local size
this->local_size = nb_local_master_dofs;
/// resize PETSc matrix
#if defined(AKANTU_USE_MPI)
ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size, this->local_size, this->size, this->size); CHKERRXX(ierr);
#else
ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size, this->local_size); CHKERRXX(ierr);
#endif
/// create mapping from akantu global numbering to petsc global numbering
this->createGlobalAkantuToPETScMap(local_master_eq_nbs.storage());
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* This method generates a mapping from the global Akantu equation
* numbering to the global PETSc dof ordering
* @param local_master_eq_nbs_ptr Int pointer to the array of equation
* numbers of all local or master dofs, i.e. the row indices of the
* local matrix
*/
void PETScMatrix::createGlobalAkantuToPETScMap(Int* local_master_eq_nbs_ptr) {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt rank = comm.whoAmI();
//initialize vector to store the number of local and master nodes that are assigned to each processor
Vector<UInt> master_local_ndofs_per_proc(nb_proc);
/// store the nb of master and local dofs on each processor
master_local_ndofs_per_proc(rank) = this->local_size;
/// exchange the information among all processors
comm.allGather(master_local_ndofs_per_proc.storage(), 1);
/// each processor creates a map for his akantu global dofs to the corresponding petsc global dofs
/// determine the PETSc-index for the first dof on each processor
for (UInt i = 0; i < rank; ++i) {
this->first_global_index += master_local_ndofs_per_proc(i);
}
/// create array for petsc ordering
Array<Int> petsc_dofs(this->local_size);
Array<Int>::scalar_iterator it_petsc_dofs = petsc_dofs.begin();
for (Int i = this->first_global_index; i < this->first_global_index + this->local_size; ++i, ++it_petsc_dofs) {
*it_petsc_dofs = i;
}
ierr = AOCreateBasic(this->petsc_matrix_wrapper->communicator, this->local_size, local_master_eq_nbs_ptr, petsc_dofs.storage(), &(this->petsc_matrix_wrapper->ao)); CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
// void PETScMatrix::createLocalAkantuToPETScMap(const DOFSynchronizer & dof_synchronizer) {
// AKANTU_DEBUG_IN();
// AKANTU_DEBUG_ASSERT(this->petsc_matrix_wrapper->ao != NULL,
// "You should first create a mapping from the global"
// << " Akantu numbering to the global PETSc numbering");
// PetscErrorCode ierr;
// this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
// /// get the number of dofs
// Int nb_dofs = dof_synchronizer.getNbDOFs();
// /// get the global equation numbers for each node
// Array<Int> global_dof_equation_numbers = dof_synchronizer.getGlobalDOFEquationNumbers();
// /// map the global dof equation numbers to the corresponding PETSc ordering
// ierr = AOApplicationToPETSc(this->petsc_matrix_wrapper->ao, nb_dofs,
// global_dof_equation_numbers.storage()); CHKERRXX(ierr);
// /// create the mapping from the local Akantu ordering to the global PETSc ordering
// ierr = ISLocalToGlobalMappingCreate(this->petsc_matrix_wrapper->communicator,
// 1, nb_dofs, global_dof_equation_numbers.storage(),
// PETSC_COPY_VALUES, &(this->petsc_matrix_wrapper-mapping)); CHKERRXX(ierr);
// AKANTU_DEBUG_OUT();
// }
/* -------------------------------------------------------------------------- */
/**
* This function creates the non-zero pattern of the PETSc matrix. In
* PETSc the parallel matrix is partitioned across processors such
* that the first m0 rows belong to process 0, the next m1 rows belong
* to process 1, the next m2 rows belong to process 2 etc.. where
* m0,m1,m2,.. are the input parameter 'm'. i.e each processor stores
* values corresponding to [m x N] submatrix
* (http://www.mcs.anl.gov/petsc/).
* @param mesh mesh discretizing the domain we want to analyze
* @param dof_synchronizer dof synchronizer that maps the local
* dofs to the global dofs and the equation numbers, i.e., the
* position at which the dof is assembled in the matrix
*/
void PETScMatrix::buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom) {
AKANTU_DEBUG_IN();
//clearProfile();
this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
this->setSize();
PetscErrorCode ierr;
/// resize arrays to store the number of nonzeros in each row
this->d_nnz.resize(this->local_size);
this->o_nnz.resize(this->local_size);
/// set arrays to zero everywhere
this->d_nnz.set(0);
this->o_nnz.set(0);
// if(irn_jcn_to_k) delete irn_jcn_to_k;
// irn_jcn_to_k = new std::map<std::pair<UInt, UInt>, UInt>;
coordinate_list_map::iterator irn_jcn_k_it;
Int * eq_nb_val = dof_synchronizer.getGlobalDOFEquationNumbers().storage();
UInt nb_global_dofs = dof_synchronizer.getNbGlobalDOFs();
Array<Int> index_pair(2);
/// Loop over all the ghost types
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
const GhostType & ghost_type = *gt;
Mesh::type_iterator it = mesh.firstType(mesh.getSpatialDimension(), ghost_type, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType (mesh.getSpatialDimension(), ghost_type, _ek_not_defined);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
UInt * conn_val = mesh.getConnectivity(*it, ghost_type).storage();
Int * local_eq_nb_val = new Int[nb_degree_of_freedom * nb_nodes_per_element];
for (UInt e = 0; e < nb_element; ++e) {
Int * tmp_local_eq_nb_val = local_eq_nb_val;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
UInt n = conn_val[i];
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
/**
* !!!!!!Careful!!!!!! This is a ugly fix. @todo this is a
* very ugly fix, because the offset for the global
* equation number, where the dof will be assembled, is
* hardcoded. In the future a class dof manager has to be
* added to Akantu to handle the mapping between the dofs
* and the equation numbers
*
*/
*tmp_local_eq_nb_val++ = eq_nb_val[n * nb_degree_of_freedom + d] - (dof_synchronizer.isPureGhostDOF(n * nb_degree_of_freedom + d) ? nb_global_dofs : 0);
}
}
for (UInt i = 0; i < size_mat; ++i) {
Int c_irn = local_eq_nb_val[i];
UInt j_start = 0;
for (UInt j = j_start; j < size_mat; ++j) {
Int c_jcn = local_eq_nb_val[j];
index_pair(0) = c_irn;
index_pair(1) = c_jcn;
AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index_pair.storage());
if (index_pair(0) >= first_global_index && index_pair(0) < first_global_index + this->local_size) {
KeyCOO irn_jcn = keyPETSc(c_irn, c_jcn);
irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
if (irn_jcn_k_it == irn_jcn_k.end()) {
irn_jcn_k[irn_jcn] = nb_non_zero;
// check if node is slave node
if (index_pair(1) >= first_global_index && index_pair(1) < first_global_index + this->local_size)
this->d_nnz(index_pair(0) - first_global_index) += 1;
else
this->o_nnz(index_pair(0) - first_global_index) += 1;
nb_non_zero++;
}
}
}
}
conn_val += nb_nodes_per_element;
}
delete [] local_eq_nb_val;
}
}
// /// for pbc @todo correct it for parallel
// if(StaticCommunicator::getStaticCommunicator().getNbProc() == 1) {
// for (UInt i = 0; i < size; ++i) {
// KeyCOO irn_jcn = key(i, i);
// irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
// if(irn_jcn_k_it == irn_jcn_k.end()) {
// irn_jcn_k[irn_jcn] = nb_non_zero;
// irn.push_back(i + 1);
// jcn.push_back(i + 1);
// nb_non_zero++;
// }
// }
// }
// std::string mat_type;
// mat_type.resize(20, 'a');
// std::cout << "MatType: " << mat_type << std::endl;
// const char * mat_type_ptr = mat_type.c_str();
MatType type;
MatGetType(this->petsc_matrix_wrapper->mat, &type);
/// std::cout << "the matrix type is: " << type << std::endl;
/**
* PETSc will use only one of the following preallocation commands
* depending on the matrix type and ignore the rest. Note that for
* the block matrix format a block size of 1 is used. This might
* result in bad performance. @todo For better results implement
* buildProfile() with larger block size.
*
*/
/// build profile:
if (strcmp(type, MATSEQAIJ) == 0) {
ierr = MatSeqAIJSetPreallocation(this->petsc_matrix_wrapper->mat,
0, d_nnz.storage()); CHKERRXX(ierr);
} else if ((strcmp(type, MATMPIAIJ) == 0)) {
ierr = MatMPIAIJSetPreallocation(this->petsc_matrix_wrapper->mat,
0, d_nnz.storage(), 0,
o_nnz.storage()); CHKERRXX(ierr);
} else {
AKANTU_DEBUG_ERROR("The type " << type << " of PETSc matrix is not handled by"
<< " akantu in the preallocation step");
}
//ierr = MatSeqSBAIJSetPreallocation(this->petsc_matrix_wrapper->mat, 1,
// 0, d_nnz.storage()); CHKERRXX(ierr);
if (this->sparse_matrix_type==_symmetric) {
/// set flag for symmetry to enable ICC/Cholesky preconditioner
ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_SYMMETRIC, PETSC_TRUE); CHKERRXX(ierr);
/// set flag for symmetric positive definite
ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_SPD, PETSC_TRUE); CHKERRXX(ierr);
}
/// once the profile has been build ignore any new nonzero locations
ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_NEW_NONZERO_LOCATIONS, PETSC_TRUE); CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Method to save the nonzero pattern and the values stored at each position
* @param filename name of the file in which the information will be stored
*/
void PETScMatrix::saveMatrix(const std::string & filename) const{
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
/// create Petsc viewer
PetscViewer viewer;
ierr = PetscViewerASCIIOpen(this->petsc_matrix_wrapper->communicator, filename.c_str(), &viewer); CHKERRXX(ierr);
/// set the format
PetscViewerSetFormat(viewer, PETSC_VIEWER_DEFAULT); CHKERRXX(ierr);
/// save the matrix
/// @todo Write should be done in serial -> might cause problems
ierr = MatView(this->petsc_matrix_wrapper->mat, viewer); CHKERRXX(ierr);
/// destroy the viewer
ierr = PetscViewerDestroy(&viewer); CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Method to add an Akantu sparse matrix to the PETSc matrix
* @param matrix Akantu sparse matrix to be added
* @param alpha the factor specifying how many times the matrix should be added
*/
void PETScMatrix::add(const SparseMatrix & matrix, Real alpha) {
PetscErrorCode ierr;
// AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
// "The two matrix don't have the same profiles");
Real val_to_add = 0;
Array<Int> index(2);
for (UInt n = 0; n < matrix.getNbNonZero(); ++n) {
UInt mat_to_add_offset = matrix.getOffset();
index(0) = matrix.getIRN()(n)-mat_to_add_offset;
index(1) = matrix.getJCN()(n)-mat_to_add_offset;
AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index.storage());
if (this->sparse_matrix_type == _symmetric && index(0) > index(1))
std::swap(index(0), index(1));
val_to_add = matrix.getA()(n) * alpha;
/// MatSetValue might be very slow for MATBAIJ, might need to use MatSetValuesBlocked
ierr = MatSetValue(this->petsc_matrix_wrapper->mat, index(0), index(1), val_to_add, ADD_VALUES); CHKERRXX(ierr);
/// chek if sparse matrix to be added is symmetric. In this case
/// the value also needs to be added at the transposed location in
/// the matrix because PETSc is using the full profile, also for symmetric matrices
if (matrix.getSparseMatrixType() == _symmetric && index(0) != index(1))
ierr = MatSetValue(this->petsc_matrix_wrapper->mat, index(1), index(0), val_to_add, ADD_VALUES); CHKERRXX(ierr);
}
this->performAssembly();
}
/* -------------------------------------------------------------------------- */
/**
* Method to add another PETSc matrix to this PETSc matrix
* @param matrix PETSc matrix to be added
* @param alpha the factor specifying how many times the matrix should be added
*/
void PETScMatrix::add(const PETScMatrix & matrix, Real alpha) {
PetscErrorCode ierr;
ierr = MatAXPY(this->petsc_matrix_wrapper->mat, alpha, matrix.petsc_matrix_wrapper->mat, SAME_NONZERO_PATTERN); CHKERRXX(ierr);
this->performAssembly();
}
/* -------------------------------------------------------------------------- */
/**
* MatSetValues() generally caches the values. The matrix is ready to
* use only after MatAssemblyBegin() and MatAssemblyEnd() have been
* called. (http://www.mcs.anl.gov/petsc/)
*/
void PETScMatrix::performAssembly() {
PetscErrorCode ierr;
ierr = MatAssemblyBegin(this->petsc_matrix_wrapper->mat, MAT_FINAL_ASSEMBLY); CHKERRXX(ierr);
ierr = MatAssemblyEnd(this->petsc_matrix_wrapper->mat, MAT_FINAL_ASSEMBLY); CHKERRXX(ierr);
}
/* -------------------------------------------------------------------------- */
/**
* Method is called when the static solver is destroyed, just before
* PETSc is finalized. So all PETSc objects need to be destroyed at
* this point.
*/
void PETScMatrix::beforeStaticSolverDestroy() {
AKANTU_DEBUG_IN();
try{
this->destroyInternalData();
} catch(...) {}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/// destroy all the PETSc data structures used for this matrix
void PETScMatrix::destroyInternalData() {
AKANTU_DEBUG_IN();
if(this->is_petsc_matrix_initialized) {
PetscErrorCode ierr;
ierr = MatDestroy(&(this->petsc_matrix_wrapper->mat)); CHKERRXX(ierr);
delete petsc_matrix_wrapper;
this->is_petsc_matrix_initialized = false;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/// access K(i, j). Works only for dofs on this processor!!!!
Real PETScMatrix::operator()(UInt i, UInt j) const{
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(this->dof_synchronizer->isLocalOrMasterDOF(i) && this->dof_synchronizer->isLocalOrMasterDOF(j), "Operator works only for dofs on this processor");
Array<Int> index(2,1);
index(0) = this->dof_synchronizer->getDOFGlobalID(i);
index(1) = this->dof_synchronizer->getDOFGlobalID(j);
AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index.storage());
Real value = 0;
PetscErrorCode ierr;
/// @todo MatGetValue might be very slow for MATBAIJ, might need to use MatGetValuesBlocked
ierr = MatGetValues(this->petsc_matrix_wrapper->mat, 1, &index(0), 1, &index(1), &value); CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
return value;
}
/* -------------------------------------------------------------------------- */
/**
* Apply Dirichlet boundary conditions by zeroing the rows and columns which correspond to blocked dofs
* @param boundary array of booleans which are true if the dof at this position is blocked
* @param block_val the value in the diagonal entry of blocked rows
*/
void PETScMatrix::applyBoundary(const Array<bool> & boundary, Real block_val) {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
/// get the global equation numbers to find the rows that need to be zeroed for the blocked dofs
Int * eq_nb_val = dof_synchronizer->getGlobalDOFEquationNumbers().storage();
/// every processor calls the MatSetZero() only for his local or master dofs. This assures that not two processors or more try to zero the same row
UInt nb_component = boundary.getNbComponent();
UInt size = boundary.getSize();
Int nb_blocked_local_master_eq_nb = 0;
Array<Int> blocked_local_master_eq_nb(this->local_size);
Int * blocked_lm_eq_nb_ptr = blocked_local_master_eq_nb.storage();
for (UInt i = 0; i < size; ++i) {
for (UInt j = 0; j < nb_component; ++j) {
UInt local_dof = i * nb_component + j;
if (boundary(i, j) == true && this->dof_synchronizer->isLocalOrMasterDOF(local_dof)) {
Int global_eq_nb = *eq_nb_val;
*blocked_lm_eq_nb_ptr = global_eq_nb;
++nb_blocked_local_master_eq_nb;
++blocked_lm_eq_nb_ptr;
}
++eq_nb_val;
}
}
blocked_local_master_eq_nb.resize(nb_blocked_local_master_eq_nb);
ierr = AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, nb_blocked_local_master_eq_nb, blocked_local_master_eq_nb.storage() ); CHKERRXX(ierr);
ierr = MatZeroRowsColumns(this->petsc_matrix_wrapper->mat, nb_blocked_local_master_eq_nb, blocked_local_master_eq_nb.storage(), block_val, 0, 0); CHKERRXX(ierr);
this->performAssembly();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/// set all entries to zero while keeping the same nonzero pattern
void PETScMatrix::clear() {
MatZeroEntries(this->petsc_matrix_wrapper->mat);
}
__END_AKANTU__
diff --git a/src/solver/petsc_matrix.hh b/src/solver/petsc_matrix.hh
index d09eae806..e0c57504d 100644
--- a/src/solver/petsc_matrix.hh
+++ b/src/solver/petsc_matrix.hh
@@ -1,146 +1,150 @@
/**
* @file petsc_matrix.hh
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Mon Jul 21 14:49:49 2014
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Aug 21 2015
*
* @brief Interface for PETSc matrices
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PETSC_MATRIX_HH__
#define __AKANTU_PETSC_MATRIX_HH__
/* -------------------------------------------------------------------------- */
#include "sparse_matrix.hh"
#include "static_communicator.hh"
#include "static_solver.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class PETScMatrixWrapper;
class PETScMatrix : public SparseMatrix, StaticSolverEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PETScMatrix(UInt size,
const SparseMatrixType & sparse_matrix_type,
const ID & id = "petsc_matrix",
const MemoryID & memory_id = 0);
PETScMatrix(const SparseMatrix & matrix,
const ID & id = "petsc_matrix",
const MemoryID & memory_id = 0);
virtual ~PETScMatrix();
private:
/// init internal PETSc matrix
void init();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// set the matrix to 0
virtual void clear();
/// fill the profil of the matrix
virtual void buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom);
/// modify the matrix to "remove" the blocked dof
virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
/// save the matrix in a ASCII file format
virtual void saveMatrix(const std::string & filename) const;
/// add a sparse matrix assuming the profile are the same
virtual void add(const SparseMatrix & matrix, Real alpha);
/// add a petsc matrix assuming the profile are the same
virtual void add(const PETScMatrix & matrix, Real alpha);
virtual void beforeStaticSolverDestroy();
Real operator()(UInt i, UInt j) const;
protected:
inline KeyCOO keyPETSc(UInt i, UInt j) const {
return std::make_pair(i, j);
}
private:
virtual void destroyInternalData();
/// set the size of the PETSc matrix
void setSize();
void createGlobalAkantuToPETScMap(Int* local_master_eq_nbs_ptr);
void createLocalAkantuToPETScMap(const DOFSynchronizer & dof_synchronizer);
/// perform assembly so that matrix is ready for use
void performAssembly();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(PETScMatrixWrapper, petsc_matrix_wrapper, PETScMatrixWrapper*);
AKANTU_GET_MACRO(LocalSize, local_size, Int);
/// AKANTU_GET_MACRO(LocalSize, local_size, Int);
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// store the PETSc structures
PETScMatrixWrapper * petsc_matrix_wrapper;
/// size of the diagonal part of the matrix partition
Int local_size;
/// number of nonzeros in every row of the diagonal part
Array<Int> d_nnz;
/// number of nonzeros in every row of the off-diagonal part
Array<Int> o_nnz;
/// the global index of the first local row
Int first_global_index;
/// bool to indicate if the matrix data has been initialized by calling MatCreate
bool is_petsc_matrix_initialized;
};
__END_AKANTU__
#endif /* __AKANTU_PETSC_MATRIX_HH__ */
diff --git a/src/solver/petsc_wrapper.hh b/src/solver/petsc_wrapper.hh
index 10ce09906..2bfd00b4b 100644
--- a/src/solver/petsc_wrapper.hh
+++ b/src/solver/petsc_wrapper.hh
@@ -1,73 +1,77 @@
/**
* @file petsc_wrapper.hh
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Mon Jul 21 17:40:41 2014
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Wed Oct 07 2015
*
* @brief Wrapper of PETSc structures
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PETSC_WRAPPER_HH__
#define __AKANTU_PETSC_WRAPPER_HH__
/* -------------------------------------------------------------------------- */
#include <mpi.h>
#include <petscmat.h>
#include <petscvec.h>
#include <petscao.h>
#include <petscis.h>
#include <petscksp.h>
__BEGIN_AKANTU__
struct PETScMatrixWrapper {
Mat mat;
AO ao;
ISLocalToGlobalMapping mapping;
/// pointer to the MPI communicator for PETSc commands
MPI_Comm communicator;
};
struct PETScSolverWrapper {
KSP ksp;
Vec solution;
Vec rhs;
/// pointer to the MPI communicator for PETSc commands
MPI_Comm communicator;
};
#if not defined(PETSC_CLANGUAGE_CXX)
extern int aka_PETScError(int ierr);
# define CHKERRXX(x) do { \
int error = aka_PETScError(x); \
if(error != 0) { \
AKANTU_EXCEPTION("Error in PETSC"); \
} \
} while(0)
#endif
__END_AKANTU__
#endif /* __AKANTU_PETSC_WRAPPER_HH__ */
diff --git a/src/solver/solver.cc b/src/solver/solver.cc
index 2cb5865f9..5fa0afd38 100644
--- a/src/solver/solver.cc
+++ b/src/solver/solver.cc
@@ -1,88 +1,90 @@
/**
* @file solver.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
- * @date last modification: Wed Nov 13 2013
+ * @date last modification: Wed Oct 07 2015
*
* @brief Solver interface class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "solver.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
SolverOptions _solver_no_options(true);
/* -------------------------------------------------------------------------- */
Solver::Solver(SparseMatrix & matrix,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id), StaticSolverEventHandler(),
matrix(&matrix),
is_matrix_allocated(false),
mesh(NULL),
communicator(StaticCommunicator::getStaticCommunicator()),
solution(NULL),
synch_registry(NULL) {
AKANTU_DEBUG_IN();
StaticSolver::getStaticSolver().registerEventHandler(*this);
//createSynchronizerRegistry();
this->synch_registry = new SynchronizerRegistry(*this);
synch_registry->registerSynchronizer(this->matrix->getDOFSynchronizer(), _gst_solver_solution);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Solver::~Solver() {
AKANTU_DEBUG_IN();
this->destroyInternalData();
delete synch_registry;
StaticSolver::getStaticSolver().unregisterEventHandler(*this);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Solver::beforeStaticSolverDestroy() {
AKANTU_DEBUG_IN();
try{
this->destroyInternalData();
} catch(...) {}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Solver::createSynchronizerRegistry() {
//this->synch_registry = new SynchronizerRegistry(this);
}
__END_AKANTU__
diff --git a/src/solver/solver.hh b/src/solver/solver.hh
index 2667fb700..dc93acadb 100644
--- a/src/solver/solver.hh
+++ b/src/solver/solver.hh
@@ -1,167 +1,168 @@
/**
* @file solver.hh
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
- * @date creation: Mon Dec 13 2010
- * @date last modification: Mon Sep 15 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief interface for solvers
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_HH__
#define __AKANTU_SOLVER_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_memory.hh"
#include "aka_array.hh"
#include "sparse_matrix.hh"
#include "mesh.hh"
#include "static_communicator.hh"
#include "static_solver.hh"
#include "data_accessor.hh"
#include "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class SolverOptions {
public:
SolverOptions(bool no_option = false) // : no_option(no_option)
{ }
virtual ~SolverOptions() {}
private:
//bool no_option;
};
extern SolverOptions _solver_no_options;
class Solver : protected Memory,
public StaticSolverEventHandler,
public DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Solver(SparseMatrix & matrix,
const ID & id = "solver",
const MemoryID & memory_id = 0);
virtual ~Solver();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the solver
virtual void initialize(SolverOptions & options = _solver_no_options) = 0;
virtual void setOperators() {};
virtual void analysis() {};
virtual void factorize() {};
/// solve
virtual void solve(Array<Real> & solution) = 0;
virtual void solve() = 0;
virtual void setRHS(Array<Real> & rhs) = 0;
/// function to print the contain of the class
// virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
virtual void destroyInternalData() {};
public:
virtual void beforeStaticSolverDestroy();
void createSynchronizerRegistry();
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
inline virtual UInt getNbDataForDOFs(const Array <UInt> & dofs,
SynchronizationTag tag) const;
inline virtual void packDOFData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
SynchronizationTag tag) const;
inline virtual void unpackDOFData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(RHS, *rhs, Array<Real> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the matrix
SparseMatrix * matrix;
/// is sparse matrix allocated
bool is_matrix_allocated;
/// the right hand side
Array<Real> * rhs;
/// mesh
const Mesh * mesh;
/// pointer to the communicator
StaticCommunicator & communicator;
/// the solution obtained from the solve step
Array<Real> * solution;
/// synchronizer registry
SynchronizerRegistry * synch_registry;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "solver_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_SOLVER_HH__ */
diff --git a/src/solver/solver_inline_impl.cc b/src/solver/solver_inline_impl.cc
index 7c47a285c..6b159b2ee 100644
--- a/src/solver/solver_inline_impl.cc
+++ b/src/solver/solver_inline_impl.cc
@@ -1,81 +1,85 @@
/**
* @file solver_inline_impl.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Thu Nov 13 14:43:41 2014
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Mon Dec 13 2010
+ * @date last modification: Wed Oct 07 2015
*
* @brief implementation of solver inline functions
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline UInt Solver::getNbDataForDOFs(const Array<UInt> & dofs,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
switch(tag) {
case _gst_solver_solution: {
size += dofs.getSize() * sizeof(Real);
break;
}
default: { }
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void Solver::packDOFData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_solver_solution: {
packDOFDataHelper(*solution, buffer, dofs);
break;
}
default: {
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void Solver::unpackDOFData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_solver_solution: {
unpackDOFDataHelper(*solution, buffer, dofs);
break;
}
default: {
}
}
AKANTU_DEBUG_OUT();
}
diff --git a/src/solver/solver_mumps.cc b/src/solver/solver_mumps.cc
index 217ed1745..9e1055037 100644
--- a/src/solver/solver_mumps.cc
+++ b/src/solver/solver_mumps.cc
@@ -1,389 +1,390 @@
/**
* @file solver_mumps.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Fri Oct 16 2015
*
* @brief implem of SolverMumps class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* @subsection Ctrl_param Control parameters
*
* ICNTL(1),
* ICNTL(2),
* ICNTL(3) : output streams for error, diagnostics, and global messages
*
* ICNTL(4) : verbose level : 0 no message - 4 all messages
*
* ICNTL(5) : type of matrix, 0 assembled, 1 elementary
*
* ICNTL(6) : control the permutation and scaling(default 7) see mumps doc for
* more information
*
* ICNTL(7) : determine the pivot order (default 7) see mumps doc for more
* information
*
* ICNTL(8) : describe the scaling method used
*
* ICNTL(9) : 1 solve A x = b, 0 solve At x = b
*
* ICNTL(10) : number of iterative refinement when NRHS = 1
*
* ICNTL(11) : > 0 return statistics
*
* ICNTL(12) : only used for SYM = 2, ordering strategy
*
* ICNTL(13) :
*
* ICNTL(14) : percentage of increase of the estimated working space
*
* ICNTL(15-17) : not used
*
* ICNTL(18) : only used if ICNTL(5) = 0, 0 matrix centralized, 1 structure on
* host and mumps give the mapping, 2 structure on host and distributed matrix
* for facto, 3 distributed matrix
*
* ICNTL(19) : > 0, Shur complement returned
*
* ICNTL(20) : 0 rhs dense, 1 rhs sparse
*
* ICNTL(21) : 0 solution in rhs, 1 solution distributed in ISOL_loc and SOL_loc
* allocated by user
*
* ICNTL(22) : 0 in-core, 1 out-of-core
*
* ICNTL(23) : maximum memory allocatable by mumps pre proc
*
* ICNTL(24) : controls the detection of "null pivot rows"
*
* ICNTL(25) :
*
* ICNTL(26) :
*
* ICNTL(27) :
*
* ICNTL(28) : 0 automatic choice, 1 sequential analysis, 2 parallel analysis
*
* ICNTL(29) : 0 automatic choice, 1 PT-Scotch, 2 ParMetis
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#if defined(AKANTU_USE_MPI)
# include "static_communicator_mpi.hh"
# include "mpi_type_wrapper.hh"
#endif
#include "solver_mumps.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
// static std::ostream & operator <<(std::ostream & stream, const DMUMPS_STRUC_C & _this) {
// stream << "DMUMPS Data [" << std::endl;
// stream << " + job : " << _this.job << std::endl;
// stream << " + par : " << _this.par << std::endl;
// stream << " + sym : " << _this.sym << std::endl;
// stream << " + comm_fortran : " << _this.comm_fortran << std::endl;
// stream << " + nz : " << _this.nz << std::endl;
// stream << " + irn : " << _this.irn << std::endl;
// stream << " + jcn : " << _this.jcn << std::endl;
// stream << " + nz_loc : " << _this.nz_loc << std::endl;
// stream << " + irn_loc : " << _this.irn_loc << std::endl;
// stream << " + jcn_loc : " << _this.jcn_loc << std::endl;
// stream << "]";
// return stream;
// }
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SolverMumps::SolverMumps(SparseMatrix & matrix,
const ID & id,
const MemoryID & memory_id) :
Solver(matrix, id, memory_id), is_mumps_data_initialized(false), rhs_is_local(true) {
AKANTU_DEBUG_IN();
#ifdef AKANTU_USE_MPI
parallel_method = SolverMumpsOptions::_fully_distributed;
#else //AKANTU_USE_MPI
parallel_method = SolverMumpsOptions::_not_parallel;
#endif //AKANTU_USE_MPI
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SolverMumps::~SolverMumps() {
AKANTU_DEBUG_IN();
this->destroyInternalData();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::destroyInternalData() {
AKANTU_DEBUG_IN();
if(this->is_mumps_data_initialized) {
this->mumps_data.job = _smj_destroy; // destroy
dmumps_c(&this->mumps_data);
this->is_mumps_data_initialized = false;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::initMumpsData() {
// Default Scaling
icntl(8) = 77;
// Assembled matrix
icntl(5) = 0;
/// Default centralized dense second member
icntl(20) = 0;
icntl(21) = 0;
icntl(28) = 0; //automatic choice for analysis analysis
switch(this->parallel_method) {
case SolverMumpsOptions::_fully_distributed:
icntl(18) = 3; //fully distributed
this->mumps_data.nz_loc = matrix->getNbNonZero();
this->mumps_data.irn_loc = matrix->getIRN().storage();
this->mumps_data.jcn_loc = matrix->getJCN().storage();
break;
case SolverMumpsOptions::_not_parallel:
case SolverMumpsOptions::_master_slave_distributed:
icntl(18) = 0; //centralized
if(prank == 0) {
this->mumps_data.nz = matrix->getNbNonZero();
this->mumps_data.irn = matrix->getIRN().storage();
this->mumps_data.jcn = matrix->getJCN().storage();
} else {
this->mumps_data.nz = 0;
this->mumps_data.irn = NULL;
this->mumps_data.jcn = NULL;
}
break;
default:
AKANTU_DEBUG_ERROR("This case should not happen!!");
}
}
/* -------------------------------------------------------------------------- */
void SolverMumps::initialize(SolverOptions & options) {
AKANTU_DEBUG_IN();
if(SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options)) {
this->parallel_method = opt->parallel_method;
}
this->mumps_data.par = 1; // The host is part of computations
switch(this->parallel_method) {
case SolverMumpsOptions::_not_parallel: break;
case SolverMumpsOptions::_master_slave_distributed:
this->mumps_data.par = 0; // The host is not part of the computations
case SolverMumpsOptions::_fully_distributed:
#ifdef AKANTU_USE_MPI
const StaticCommunicatorMPI & mpi_st_comm = dynamic_cast<const StaticCommunicatorMPI &>(communicator.getRealStaticCommunicator());
this->mumps_data.comm_fortran = MPI_Comm_c2f(mpi_st_comm.getMPITypeWrapper().getMPICommunicator());
#endif
break;
}
this->mumps_data.sym = 2 * (matrix->getSparseMatrixType() == _symmetric);
this->prank = communicator.whoAmI();
this->mumps_data.job = _smj_initialize; //initialize
dmumps_c(&this->mumps_data);
this->is_mumps_data_initialized = true;
/* ------------------------------------------------------------------------ */
UInt size = matrix->getSize();
if(prank == 0) {
std::stringstream sstr_rhs; sstr_rhs << id << ":rhs";
this->rhs = &(alloc<Real>(sstr_rhs.str(), size, 1, 0.));
} else {
this->rhs = NULL;
}
this->mumps_data.nz_alloc = 0;
this->mumps_data.n = size;
/* ------------------------------------------------------------------------ */
// Output setup
if(AKANTU_DEBUG_TEST(dblTrace)) {
icntl(1) = 6;
icntl(2) = 2;
icntl(3) = 2;
icntl(4) = 4;
} else {
/// No outputs
icntl(1) = 6; // error output
icntl(2) = 0; // dignostics output
icntl(3) = 0; // informations
icntl(4) = 0; // no outputs
}
if(AKANTU_DEBUG_TEST(dblDump)) {
strcpy(this->mumps_data.write_problem, "mumps_matrix.mtx");
}
this->analysis();
// icntl(14) = 80;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::setRHS(Array<Real> & rhs) {
if(prank == 0) {
//std::copy(rhs.storage(), rhs.storage() + this->rhs->getSize(), this->rhs->storage());
DebugLevel dbl = debug::getDebugLevel();
debug::setDebugLevel(dblError);
matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
debug::setDebugLevel(dbl);
} else {
this->matrix->getDOFSynchronizer().gather(rhs, 0);
}
}
/* -------------------------------------------------------------------------- */
void SolverMumps::analysis() {
AKANTU_DEBUG_IN();
initMumpsData();
this->mumps_data.job = _smj_analyze; //analyze
dmumps_c(&this->mumps_data);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::factorize() {
AKANTU_DEBUG_IN();
if(parallel_method == SolverMumpsOptions::_fully_distributed)
this->mumps_data.a_loc = this->matrix->getA().storage();
else {
if(prank == 0)
this->mumps_data.a = this->matrix->getA().storage();
}
if(prank == 0) {
this->mumps_data.rhs = this->rhs->storage();
}
this->mumps_data.job = _smj_factorize; // factorize
dmumps_c(&this->mumps_data);
this->printError();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::solve() {
AKANTU_DEBUG_IN();
if(prank == 0) {
this->mumps_data.rhs = this->rhs->storage();
}
this->mumps_data.job = _smj_solve; // solve
dmumps_c(&this->mumps_data);
this->printError();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::solve(Array<Real> & solution) {
AKANTU_DEBUG_IN();
this->solve();
if(prank == 0) {
matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
// std::copy(this->rhs->storage(), this->rhs->storage() + this->rhs->getSize(), solution.storage());
} else {
this->matrix->getDOFSynchronizer().scatter(solution, 0);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::printError() {
Int _info_v[2];
_info_v[0] = info(1); // to get errors
_info_v[1] = -info(1); // to get warnings
communicator.allReduce(_info_v, 2, _so_min);
_info_v[1] = -_info_v[1];
if(_info_v[0] < 0) { // < 0 is an error
switch(_info_v[0]) {
case -10: AKANTU_DEBUG_ERROR("The matrix is singular"); break;
case -9: {
icntl(14) += 10;
if(icntl(14) != 90) {
//std::cout << "Dynamic memory increase of 10%" << std::endl;
AKANTU_DEBUG_WARNING("MUMPS dynamic memory is insufficient it will be increased of 10%");
this->analysis();
this->factorize();
this->solve();
} else {
AKANTU_DEBUG_ERROR("The MUMPS workarray is too small INFO(2)=" << info(2) << "No further increase possible"); break;
}
}
default:
AKANTU_DEBUG_ERROR("Error in mumps during solve process, check mumps user guide INFO(1) = "
<< _info_v[1]);
}
} else if (_info_v[1] > 0) {
AKANTU_DEBUG_WARNING("Warning in mumps during solve process, check mumps user guide INFO(1) = "
<< _info_v[1]);
}
}
__END_AKANTU__
diff --git a/src/solver/solver_mumps.hh b/src/solver/solver_mumps.hh
index c843439d1..fdbeeadd2 100644
--- a/src/solver/solver_mumps.hh
+++ b/src/solver/solver_mumps.hh
@@ -1,154 +1,155 @@
/**
* @file solver_mumps.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Dec 13 2010
- * @date last modification: Mon Sep 15 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Oct 16 2015
*
* @brief Solver class implementation for the mumps solver
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_MUMPS_HH__
#define __AKANTU_SOLVER_MUMPS_HH__
#include <dmumps_c.h>
#include "solver.hh"
#include "static_communicator.hh"
__BEGIN_AKANTU__
class SolverMumpsOptions : public SolverOptions {
public:
enum ParallelMethod {
_not_parallel,
_fully_distributed,
_master_slave_distributed
};
SolverMumpsOptions(ParallelMethod parallel_method = _fully_distributed) :
SolverOptions(),
parallel_method(parallel_method) { }
private:
friend class SolverMumps;
ParallelMethod parallel_method;
};
class SolverMumps : public Solver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SolverMumps(SparseMatrix & sparse_matrix,
const ID & id = "solver_mumps",
const MemoryID & memory_id = 0);
virtual ~SolverMumps();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// build the profile and do the analysis part
virtual void initialize(SolverOptions & options = _solver_no_options);
void initializeSlave(SolverOptions & options = _solver_no_options);
/// analysis (symbolic facto + permutations)
virtual void analysis();
/// factorize the matrix
virtual void factorize();
/// solve the system
virtual void solve(Array<Real> & solution);
virtual void solve();
void solveSlave();
virtual void setRHS(Array<Real> & rhs);
private:
/// print the error if any happened in mumps
void printError();
/// clean the mumps info
virtual void destroyInternalData();
/// set internal values;
void initMumpsData();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
private:
/// access the control variable
inline Int & icntl(UInt i) {
return mumps_data.icntl[i - 1];
}
/// access the results info
inline Int & info(UInt i) {
return mumps_data.info[i - 1];
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// mumps data
DMUMPS_STRUC_C mumps_data;
/// specify if the mumps_data are initialized or not
bool is_mumps_data_initialized;
UInt prank;
/* ------------------------------------------------------------------------ */
/* Local types */
/* ------------------------------------------------------------------------ */
private:
SolverMumpsOptions::ParallelMethod parallel_method;
bool rhs_is_local;
enum SolverMumpsJob {
_smj_initialize = -1,
_smj_analyze = 1,
_smj_factorize = 2,
_smj_solve = 3,
_smj_analyze_factorize = 4,
_smj_factorize_solve = 5,
_smj_complete = 6, // analyze, factorize, solve
_smj_destroy = -2
};
};
__END_AKANTU__
#endif /* __AKANTU_SOLVER_MUMPS_HH__ */
diff --git a/src/solver/solver_petsc.cc b/src/solver/solver_petsc.cc
index 0c7f9f61e..bd5870127 100644
--- a/src/solver/solver_petsc.cc
+++ b/src/solver/solver_petsc.cc
@@ -1,1109 +1,1110 @@
/**
* @file solver_petsc.cc
*
+ * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- # @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
- * @date Mon Dec 13 10:48:06 2010
+ * @date creation: Tue May 13 2014
+ * @date last modification: Fri Oct 16 2015
*
* @brief Solver class implementation for the petsc solver
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <petscksp.h>
#include "solver_petsc.hh"
#include "petsc_wrapper.hh"
#include "petsc_matrix.hh"
#include "static_communicator.hh"
#include "static_communicator_mpi.hh"
#include "mpi_type_wrapper.hh"
#include "dof_synchronizer.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SolverPETSc::SolverPETSc(SparseMatrix & matrix,
const ID & id,
const MemoryID & memory_id) :
Solver(matrix, id, memory_id), is_petsc_data_initialized(false),
petsc_solver_wrapper(new PETScSolverWrapper) {
}
/* -------------------------------------------------------------------------- */
SolverPETSc::~SolverPETSc() {
AKANTU_DEBUG_IN();
this->destroyInternalData();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::destroyInternalData() {
AKANTU_DEBUG_IN();
if(this->is_petsc_data_initialized) {
PetscErrorCode ierr;
ierr = KSPDestroy(&(this->petsc_solver_wrapper->ksp)); CHKERRXX(ierr);
ierr = VecDestroy(&(this->petsc_solver_wrapper->rhs)); CHKERRXX(ierr);
ierr = VecDestroy(&(this->petsc_solver_wrapper->solution)); CHKERRXX(ierr);
delete petsc_solver_wrapper;
this->is_petsc_data_initialized = false;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::initialize(SolverOptions & options) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_USE_MPI)
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
const StaticCommunicatorMPI & mpi_st_comm =
dynamic_cast<const StaticCommunicatorMPI &>(comm.getRealStaticCommunicator());
this->petsc_solver_wrapper->communicator = mpi_st_comm.getMPITypeWrapper().getMPICommunicator();
#else
this->petsc_solver_wrapper->communicator = PETSC_COMM_SELF;
#endif
PetscErrorCode ierr;
PETScMatrix * petsc_matrix = static_cast<PETScMatrix*>(this->matrix);
/// create a solver context
ierr = KSPCreate(this->petsc_solver_wrapper->communicator, &(this->petsc_solver_wrapper->ksp)); CHKERRXX(ierr);
/// create the PETSc vector for the right-hand side
ierr = VecCreate(this->petsc_solver_wrapper->communicator, &(this->petsc_solver_wrapper->rhs)); CHKERRXX(ierr);
ierr = VecSetSizes((this->petsc_solver_wrapper->rhs),
petsc_matrix->getLocalSize(),
petsc_matrix->getSize()); CHKERRXX(ierr);
ierr = VecSetFromOptions((this->petsc_solver_wrapper->rhs)); CHKERRXX(ierr);
/// create the PETSc vector for the solution
ierr = VecDuplicate((this->petsc_solver_wrapper->rhs), &(this->petsc_solver_wrapper->solution)); CHKERRXX(ierr);
/// set the solution to zero
ierr = VecZeroEntries(this->petsc_solver_wrapper->solution);
this->is_petsc_data_initialized = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::setRHS(Array<Real> & rhs) {
PetscErrorCode ierr;
PETScMatrix * petsc_matrix = static_cast<PETScMatrix*>(this->matrix);
UInt nb_component = rhs.getNbComponent();
UInt size = rhs.getSize();
for (UInt i = 0; i < size; ++i) {
for (UInt j = 0; j < nb_component; ++j) {
UInt i_local = i * nb_component + j;
if (this->matrix->getDOFSynchronizer().isLocalOrMasterDOF(i_local)) {
Int i_global = this->matrix->getDOFSynchronizer().getDOFGlobalID(i_local);
AOApplicationToPetsc(petsc_matrix->getPETScMatrixWrapper()->ao, 1, &(i_global) );
ierr = VecSetValue((this->petsc_solver_wrapper->rhs), i_global, rhs(i,j), INSERT_VALUES); CHKERRXX(ierr);
}
}
}
ierr = VecAssemblyBegin(this->petsc_solver_wrapper->rhs); CHKERRXX(ierr);
ierr = VecAssemblyEnd(this->petsc_solver_wrapper->rhs); CHKERRXX(ierr);
/// ierr = VecCopy((this->petsc_solver_wrapper->rhs), (this->petsc_solver_wrapper->solution)); CHKERRXX(ierr);
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::solve() {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
ierr = KSPSolve(this->petsc_solver_wrapper->ksp, this->petsc_solver_wrapper->rhs, this->petsc_solver_wrapper->solution); CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::solve(Array<Real> & solution) {
AKANTU_DEBUG_IN();
this->solution = &solution;
this->solve();
PetscErrorCode ierr;
PETScMatrix * petsc_matrix = static_cast<PETScMatrix*>(this->matrix);
// ierr = VecGetOwnershipRange(this->petsc_solver_wrapper->solution, solution_begin, solution_end); CHKERRXX(ierr);
// ierr = VecGetArray(this->petsc_solver_wrapper->solution, PetscScalar **array); CHKERRXX(ierr);
UInt nb_component = solution.getNbComponent();
UInt size = solution.getSize();
for (UInt i = 0; i < size; ++i) {
for (UInt j = 0; j < nb_component; ++j) {
UInt i_local = i * nb_component + j;
if (this->matrix->getDOFSynchronizer().isLocalOrMasterDOF(i_local)) {
Int i_global = this->matrix->getDOFSynchronizer().getDOFGlobalID(i_local);
ierr = AOApplicationToPetsc(petsc_matrix->getPETScMatrixWrapper()->ao, 1, &(i_global) ); CHKERRXX(ierr);
ierr = VecGetValues(this->petsc_solver_wrapper->solution, 1, &i_global, &solution(i,j)); CHKERRXX(ierr);
}
}
}
synch_registry->synchronize(_gst_solver_solution);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::setOperators() {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
/// set the matrix that defines the linear system and the matrix for preconditioning (here they are the same)
PETScMatrix * petsc_matrix = static_cast<PETScMatrix*>(this->matrix);
#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
ierr = KSPSetOperators(this->petsc_solver_wrapper->ksp, petsc_matrix->getPETScMatrixWrapper()->mat, petsc_matrix->getPETScMatrixWrapper()->mat); CHKERRXX(ierr);
#else
ierr = KSPSetOperators(this->petsc_solver_wrapper->ksp, petsc_matrix->getPETScMatrixWrapper()->mat, petsc_matrix->getPETScMatrixWrapper()->mat, SAME_NONZERO_PATTERN); CHKERRXX(ierr);
#endif
/// If this is not called the solution vector is zeroed in the call to KSPSolve().
ierr = KSPSetInitialGuessNonzero(this->petsc_solver_wrapper->ksp, PETSC_TRUE); CHKERRXX(ierr);
ierr = KSPSetFromOptions(this->petsc_solver_wrapper->ksp); CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
// void finalize_petsc() {
// static bool finalized = false;
// if (!finalized) {
// cout<<"*** INFO *** PETSc is finalizing..."<<endl;
// // finalize PETSc
// PetscErrorCode ierr = PetscFinalize();CHKERRCONTINUE(ierr);
// finalized = true;
// }
// }
// SolverPETSc::sparse_vector_type
// SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& AA,
// const SolverPETSc::sparse_vector_type& bb) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside PETSc solver: "<<timer<<endl;
// #endif
// #ifdef CPPUTILS_VERBOSE
// out<<" Inside operator()(const sparse_matrix_type&, const sparse_vector_type&)... "<<timer<<endl;
// #endif
// assert(AA.rows() == bb.size());
// // KSP ksp; //!< linear solver context
// Vec b; /* RHS */
// PC pc; /* preconditioner context */
// PetscErrorCode ierr;
// PetscInt nlocal;
// PetscInt n = bb.size();
// VecScatter ctx;
// /*
// Create vectors. Note that we form 1 vector from scratch and
// then duplicate as needed. For this simple case let PETSc decide how
// many elements of the vector are stored on each processor. The second
// argument to VecSetSizes() below causes PETSc to decide.
// */
// ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(b,PETSC_DECIDE,n);CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(b);CHKERRCONTINUE(ierr);
// if (!allocated_) {
// ierr = VecDuplicate(b,&x_);CHKERRCONTINUE(ierr);
// } else
// VecZeroEntries(x_);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vectors created... "<<timer<<endl;
// #endif
// /* Set hight-hand-side vector */
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(b, 1, &row, &it->second, ADD_VALUES);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Right hand side set... "<<timer<<endl;
// #endif
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(b);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(b);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Right-hand-side vector assembled... "<<timer<<endl;
// ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// Vec b_all;
// ierr = VecScatterCreateToAll(b, &ctx, &b_all);CHKERRCONTINUE(ierr);
// ierr = VecScatterBegin(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// ierr = VecScatterEnd(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// value_type nrm;
// VecNorm(b_all,NORM_2,&nrm);
// out<<" Norm of right hand side... "<<nrm<<endl;
// #endif
// /* Identify the starting and ending mesh points on each
// processor for the interior part of the mesh. We let PETSc decide
// above. */
// // PetscInt rstart,rend;
// // ierr = VecGetOwnershipRange(x_,&rstart,&rend);CHKERRCONTINUE(ierr);
// ierr = VecGetLocalSize(x_,&nlocal);CHKERRCONTINUE(ierr);
// /*
// Create matrix. When using MatCreate(), the matrix format can
// be specified at runtime.
// Performance tuning note: For problems of substantial size,
// preallocation of matrix memory is crucial for attaining good
// performance. See the matrix chapter of the users manual for details.
// We pass in nlocal as the "local" size of the matrix to force it
// to have the same parallel layout as the vector created above.
// */
// if (!allocated_) {
// ierr = MatCreate(PETSC_COMM_WORLD,&A_);CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(A_,nlocal,nlocal,n,n);CHKERRCONTINUE(ierr);
// ierr = MatSetFromOptions(A_);CHKERRCONTINUE(ierr);
// ierr = MatSetUp(A_);CHKERRCONTINUE(ierr);
// } else {
// // zero-out matrix
// MatZeroEntries(A_);
// }
// /*
// Assemble matrix.
// The linear system is distributed across the processors by
// chunks of contiguous rows, which correspond to contiguous
// sections of the mesh on which the problem is discretized.
// For matrix assembly, each processor contributes entries for
// the part that it owns locally.
// */
// #ifdef CPPUTILS_VERBOSE
// out<<" Zeroed-out sparse matrix entries... "<<timer<<endl;
// #endif
// for (sparse_matrix_type::const_hash_iterator it = AA.map_.begin(); it != AA.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = AA.unhash(it->first);
// PetscInt row = subs.first;
// PetscInt col = subs.second;
// ierr = MatSetValues(A_, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Filled sparse matrix... "<<timer<<endl;
// #endif
// /* Assemble the matrix */
// ierr = MatAssemblyBegin(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// if (!allocated_) {
// // set after the first MatAssemblyEnd
// // ierr = MatSetOption(A_, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE);CHKERRCONTINUE(ierr);
// ierr = MatSetOption(A_, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Sparse matrix assembled... "<<timer<<endl;
// // view matrix
// MatView(A_, PETSC_VIEWER_STDOUT_WORLD);
// MatNorm(A_,NORM_FROBENIUS,&nrm);
// out<<" Norm of stiffness matrix... "<<nrm<<endl;
// #endif
// /*
// Set operators. Here the matrix that defines the linear system
// also serves as the preconditioning matrix.
// */
// // ierr = KSPSetOperators(ksp,A_,A_,DIFFERENT_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
// ierr = KSPSetOperators(ksp_,A_,A_,SAME_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
// //
// // /*
// // Set runtime options, e.g.,
// // -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
// // These options will override those specified above as long as
// // KSPSetFromOptions() is called _after_ any other customization
// // routines.
// // */
// // ierr = KSPSetFromOptions(ksp);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Solving system... "<<timer<<endl;
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Solve the linear system
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// /*
// Solve linear system
// */
// ierr = KSPSolve(ksp_,b,x_);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// /*
// View solver info; we could instead use the option -ksp_view to
// print this info to the screen at the conclusion of KSPSolve().
// */
// ierr = KSPView(ksp_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// int iter;
// KSPGetIterationNumber(ksp_, &iter);
// out<<" System solved in "<<iter<<" iterations... "<<timer<<endl;
// KSPConvergedReason reason;
// ierr = KSPGetConvergedReason(ksp_,&reason);CHKERRCONTINUE(ierr);
// if (reason < 0)
// out<<"*** WARNING *** PETSc solver diverged with flag ";
// else
// out<<"*** INFO *** PETSc solver converged with flag ";
// if (reason == KSP_CONVERGED_RTOL)
// out<<"KSP_CONVERGED_RTOL"<<endl;
// else if (reason == KSP_CONVERGED_ATOL)
// out<<"KSP_CONVERGED_ATOL"<<endl;
// else if (reason == KSP_CONVERGED_ITS)
// out<<"KSP_CONVERGED_ITS"<<endl;
// else if (reason == KSP_CONVERGED_CG_NEG_CURVE)
// out<<"KSP_CONVERGED_CG_NEG_CURVE"<<endl;
// else if (reason == KSP_CONVERGED_CG_CONSTRAINED)
// out<<"KSP_CONVERGED_CG_CONSTRAINED"<<endl;
// else if (reason == KSP_CONVERGED_STEP_LENGTH)
// out<<"KSP_CONVERGED_STEP_LENGTH"<<endl;
// else if (reason == KSP_CONVERGED_HAPPY_BREAKDOWN)
// out<<"KSP_CONVERGED_HAPPY_BREAKDOWN"<<endl;
// else if (reason == KSP_DIVERGED_NULL)
// out<<"KSP_DIVERGED_NULL"<<endl;
// else if (reason == KSP_DIVERGED_ITS)
// out<<"KSP_DIVERGED_ITS"<<endl;
// else if (reason == KSP_DIVERGED_DTOL)
// out<<"KSP_DIVERGED_DTOL"<<endl;
// else if (reason == KSP_DIVERGED_BREAKDOWN)
// out<<"KSP_DIVERGED_BREAKDOWN"<<endl;
// else if (reason == KSP_DIVERGED_BREAKDOWN_BICG)
// out<<"KSP_DIVERGED_BREAKDOWN_BICG"<<endl;
// else if (reason == KSP_DIVERGED_NONSYMMETRIC)
// out<<"KSP_DIVERGED_NONSYMMETRIC"<<endl;
// else if (reason == KSP_DIVERGED_INDEFINITE_PC)
// out<<"KSP_DIVERGED_INDEFINITE_PC"<<endl;
// else if (reason == KSP_DIVERGED_NAN)
// out<<"KSP_DIVERGED_NAN"<<endl;
// else if (reason == KSP_DIVERGED_INDEFINITE_MAT)
// out<<"KSP_DIVERGED_INDEFINITE_MAT"<<endl;
// else if (reason == KSP_CONVERGED_ITERATING)
// out<<"KSP_CONVERGED_ITERATING"<<endl;
// PetscReal rnorm;
// ierr = KSPGetResidualNorm(ksp_,&rnorm);CHKERRCONTINUE(ierr);
// out<<"PETSc last residual norm computed: "<<rnorm<<endl;
// ierr = VecView(x_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// VecNorm(x_,NORM_2,&nrm);
// out<<" Norm of solution vector... "<<nrm<<endl;
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check solution and clean up
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// Vec x_all;
// ierr = VecScatterCreateToAll(x_, &ctx, &x_all);CHKERRCONTINUE(ierr);
// ierr = VecScatterBegin(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// ierr = VecScatterEnd(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Solution vector scattered... "<<timer<<endl;
// VecNorm(x_all,NORM_2,&nrm);
// out<<" Norm of scattered vector... "<<nrm<<endl;
// // ierr = VecView(x_all,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Get values from solution and store them in the object that will be
// returned
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// sparse_vector_type xx(bb.size());
// /* Set solution vector */
// double zero = 0.;
// double val;
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecGetValues(x_all, 1, &row, &val);
// if (val != zero)
// xx[row] = val;
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Solution vector copied... "<<timer<<endl;
// // out<<" Norm of copied solution vector... "<<norm(xx, Insert_t)<<endl;
// #endif
// /*
// Free work space. All PETSc objects should be destroyed when they
// are no longer needed.
// */
// ierr = VecDestroy(&b);CHKERRCONTINUE(ierr);
// // ierr = KSPDestroy(&ksp);CHKERRCONTINUE(ierr);
// // set allocated flag
// if (!allocated_) {
// allocated_ = true;
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return xx;
// }
// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& KKpf, const SolverPETSc::sparse_matrix_type& KKpp, const SolverPETSc::sparse_vector_type& UUp) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::operator()(const sparse_matrix&, const sparse_matrix&, const sparse_vector&). "<<timer<<endl;
// #endif
// Mat Kpf, Kpp;
// Vec Up, Pf, Pp;
// PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&Kpf);CHKERRCONTINUE(ierr);
// ierr = MatCreate(PETSC_COMM_WORLD,&Kpp);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Allocating memory... "<<timer<<endl;
// #endif
// ierr = MatSetFromOptions(Kpf);CHKERRCONTINUE(ierr);
// ierr = MatSetFromOptions(Kpp);CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(Kpf,PETSC_DECIDE,PETSC_DECIDE, KKpf.rows(), KKpf.columns());CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(Kpp,PETSC_DECIDE,PETSC_DECIDE, KKpp.rows(), KKpp.columns());CHKERRCONTINUE(ierr);
// // get number of non-zeros in both diagonal and non-diagonal portions of the matrix
// std::pair<size_t,size_t> Kpf_nz = KKpf.non_zero_off_diagonal();
// std::pair<size_t,size_t> Kpp_nz = KKpp.non_zero_off_diagonal();
// ierr = MatMPIAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL, Kpf_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
// ierr = MatMPIAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL, Kpp_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
// ierr = MatSeqAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL); CHKERRCONTINUE(ierr);
// ierr = MatSeqAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL); CHKERRCONTINUE(ierr);
// for (sparse_matrix_type::const_hash_iterator it = KKpf.map_.begin(); it != KKpf.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = KKpf.unhash(it->first);
// int row = subs.first;
// int col = subs.second;
// ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
// }
// for (sparse_matrix_type::const_hash_iterator it = KKpp.map_.begin(); it != KKpp.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = KKpp.unhash(it->first);
// int row = subs.first;
// int col = subs.second;
// ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Filled sparse matrices... "<<timer<<endl;
// #endif
// /*
// Assemble matrix, using the 2-step process:
// MatAssemblyBegin(), MatAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = MatAssemblyBegin(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyBegin(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Sparse matrices assembled... "<<timer<<endl;
// #endif
// ierr = VecCreate(PETSC_COMM_WORLD,&Up);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(Up,PETSC_DECIDE, UUp.size());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(Up);CHKERRCONTINUE(ierr);
// ierr = VecCreate(PETSC_COMM_WORLD,&Pf);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(Pf,PETSC_DECIDE, KKpf.rows());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(Pf);CHKERRCONTINUE(ierr);
// ierr = VecDuplicate(Pf,&Pp);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vectors created... "<<timer<<endl;
// #endif
// /* Set hight-hand-side vector */
// for (sparse_vector_type::const_hash_iterator it = UUp.map_.begin(); it != UUp.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(Up, 1, &row, &it->second, ADD_VALUES);
// }
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(Up);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(Up);CHKERRCONTINUE(ierr);
// // add Kpf*Uf
// ierr = MatMult(Kpf, x_, Pf);
// // add Kpp*Up
// ierr = MatMultAdd(Kpp, Up, Pf, Pp);
// #ifdef CPPUTILS_VERBOSE
// out<<" Matrices multiplied... "<<timer<<endl;
// #endif
// VecScatter ctx;
// Vec Pp_all;
// ierr = VecScatterCreateToAll(Pp, &ctx, &Pp_all);CHKERRCONTINUE(ierr);
// ierr = VecScatterBegin(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// ierr = VecScatterEnd(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector scattered... "<<timer<<endl;
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Get values from solution and store them in the object that will be
// returned
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// sparse_vector_type pp(KKpf.rows());
// // get reaction vector
// for (int i=0; i<KKpf.rows(); ++i) {
// PetscScalar v;
// ierr = VecGetValues(Pp_all, 1, &i, &v);
// if (v != PetscScalar())
// pp[i] = v;
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector copied... "<<timer<<endl;
// #endif
// ierr = MatDestroy(&Kpf);CHKERRCONTINUE(ierr);
// ierr = MatDestroy(&Kpp);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Up);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Pf);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Pp);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Pp_all);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return pp;
// }
// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const SolverPETSc::sparse_vector_type& aa, const SolverPETSc::sparse_vector_type& bb) {
// assert(aa.size() == bb.size());
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::operator()(const sparse_vector&, const sparse_vector&). "<<timer<<endl;
// #endif
// Vec r;
// PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vectors created... "<<timer<<endl;
// #endif
// // set values
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
// }
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
// }
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
// sparse_vector_type rr(aa.size());
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
// int row = it->first;
// ierr = VecGetValues(r, 1, &row, &rr[row]);
// }
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecGetValues(r, 1, &row, &rr[row]);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector copied... "<<timer<<endl;
// #endif
// ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return rr;
// }
// SolverPETSc::value_type SolverPETSc::norm(const SolverPETSc::sparse_matrix_type& aa, Element_insertion_type flag) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::norm(const sparse_matrix&). "<<timer<<endl;
// #endif
// Mat r;
// PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(r,PETSC_DECIDE,PETSC_DECIDE, aa.rows(), aa.columns());CHKERRCONTINUE(ierr);
// ierr = MatSetFromOptions(r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Matrix created... "<<timer<<endl;
// #endif
// // set values
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = aa.unhash(it->first);
// int row = subs.first;
// int col = subs.second;
// if (flag == Add_t)
// ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, ADD_VALUES);
// else if (flag == Insert_t)
// ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, INSERT_VALUES);
// CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Matrix filled..."<<timer<<endl;
// #endif
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = MatAssemblyBegin(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// value_type nrm;
// MatNorm(r,NORM_FROBENIUS,&nrm);
// #ifdef CPPUTILS_VERBOSE
// out<<" Norm computed... "<<timer<<endl;
// #endif
// ierr = MatDestroy(&r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return nrm;
// }
// SolverPETSc::value_type SolverPETSc::norm(const SolverPETSc::sparse_vector_type& aa, Element_insertion_type flag) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::norm(const sparse_vector&). "<<timer<<endl;
// #endif
// Vec r;
// PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector created... "<<timer<<endl;
// #endif
// // set values
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
// int row = it->first;
// if (flag == Add_t)
// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
// else if (flag == Insert_t)
// ierr = VecSetValues(r, 1, &row, &it->second, INSERT_VALUES);
// CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector filled..."<<timer<<endl;
// #endif
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
// value_type nrm;
// VecNorm(r,NORM_2,&nrm);
// #ifdef CPPUTILS_VERBOSE
// out<<" Norm computed... "<<timer<<endl;
// #endif
// ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return nrm;
// }
// //
// ///* -------------------------------------------------------------------------- */
// //SolverMumps::SolverMumps(SparseMatrix & matrix,
// // const ID & id,
// // const MemoryID & memory_id) :
// //Solver(matrix, id, memory_id), is_mumps_data_initialized(false), rhs_is_local(true) {
// // AKANTU_DEBUG_IN();
// //
// //#ifdef AKANTU_USE_MPI
// // parallel_method = SolverMumpsOptions::_fully_distributed;
// //#else //AKANTU_USE_MPI
// // parallel_method = SolverMumpsOptions::_master_slave_distributed;
// //#endif //AKANTU_USE_MPI
// //
// // CommunicatorEventHandler & comm_event_handler = *this;
// //
// // communicator.registerEventHandler(comm_event_handler);
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///* -------------------------------------------------------------------------- */
// //SolverMumps::~SolverMumps() {
// // AKANTU_DEBUG_IN();
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///* -------------------------------------------------------------------------- */
// //void SolverMumps::destroyMumpsData() {
// // AKANTU_DEBUG_IN();
// //
// // if(is_mumps_data_initialized) {
// // mumps_data.job = _smj_destroy; // destroy
// // dmumps_c(&mumps_data);
// // is_mumps_data_initialized = false;
// // }
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///* -------------------------------------------------------------------------- */
// //void SolverMumps::onCommunicatorFinalize(const StaticCommunicator & comm) {
// // AKANTU_DEBUG_IN();
// //
// // try{
// // const StaticCommunicatorMPI & comm_mpi =
// // dynamic_cast<const StaticCommunicatorMPI &>(comm.getRealStaticCommunicator());
// // if(mumps_data.comm_fortran == MPI_Comm_c2f(comm_mpi.getMPICommunicator()))
// // destroyMumpsData();
// // } catch(...) {}
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///* -------------------------------------------------------------------------- */
// //void SolverMumps::initMumpsData(SolverMumpsOptions::ParallelMethod parallel_method) {
// // switch(parallel_method) {
// // case SolverMumpsOptions::_fully_distributed:
// // icntl(18) = 3; //fully distributed
// // icntl(28) = 0; //automatic choice
// //
// // mumps_data.nz_loc = matrix->getNbNonZero();
// // mumps_data.irn_loc = matrix->getIRN().values;
// // mumps_data.jcn_loc = matrix->getJCN().values;
// // break;
// // case SolverMumpsOptions::_master_slave_distributed:
// // if(prank == 0) {
// // mumps_data.nz = matrix->getNbNonZero();
// // mumps_data.irn = matrix->getIRN().values;
// // mumps_data.jcn = matrix->getJCN().values;
// // } else {
// // mumps_data.nz = 0;
// // mumps_data.irn = NULL;
// // mumps_data.jcn = NULL;
// //
// // icntl(18) = 0; //centralized
// // icntl(28) = 0; //sequential analysis
// // }
// // break;
// // }
// //}
// //
// ///* -------------------------------------------------------------------------- */
// //void SolverMumps::initialize(SolverOptions & options) {
// // AKANTU_DEBUG_IN();
// //
// // mumps_data.par = 1;
// //
// // if(SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options)) {
// // if(opt->parallel_method == SolverMumpsOptions::_master_slave_distributed) {
// // mumps_data.par = 0;
// // }
// // }
// //
// // mumps_data.sym = 2 * (matrix->getSparseMatrixType() == _symmetric);
// // prank = communicator.whoAmI();
// //#ifdef AKANTU_USE_MPI
// // mumps_data.comm_fortran = MPI_Comm_c2f(dynamic_cast<const StaticCommunicatorMPI &>(communicator.getRealStaticCommunicator()).getMPICommunicator());
// //#endif
// //
// // if(AKANTU_DEBUG_TEST(dblTrace)) {
// // icntl(1) = 2;
// // icntl(2) = 2;
// // icntl(3) = 2;
// // icntl(4) = 4;
// // }
// //
// // mumps_data.job = _smj_initialize; //initialize
// // dmumps_c(&mumps_data);
// // is_mumps_data_initialized = true;
// //
// // /* ------------------------------------------------------------------------ */
// // UInt size = matrix->getSize();
// //
// // if(prank == 0) {
// // std::stringstream sstr_rhs; sstr_rhs << id << ":rhs";
// // rhs = &(alloc<Real>(sstr_rhs.str(), size, 1, REAL_INIT_VALUE));
// // } else {
// // rhs = NULL;
// // }
// //
// // /// No outputs
// // icntl(1) = 0;
// // icntl(2) = 0;
// // icntl(3) = 0;
// // icntl(4) = 0;
// // mumps_data.nz_alloc = 0;
// //
// // if (AKANTU_DEBUG_TEST(dblDump)) icntl(4) = 4;
// //
// // mumps_data.n = size;
// //
// // if(AKANTU_DEBUG_TEST(dblDump)) {
// // strcpy(mumps_data.write_problem, "mumps_matrix.mtx");
// // }
// //
// // /* ------------------------------------------------------------------------ */
// // // Default Scaling
// // icntl(8) = 77;
// //
// // icntl(5) = 0; // Assembled matrix
// //
// // SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options);
// // if(opt)
// // parallel_method = opt->parallel_method;
// //
// // initMumpsData(parallel_method);
// //
// // mumps_data.job = _smj_analyze; //analyze
// // dmumps_c(&mumps_data);
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///* -------------------------------------------------------------------------- */
// //void SolverMumps::setRHS(Array<Real> & rhs) {
// // if(prank == 0) {
// // matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
// // } else {
// // matrix->getDOFSynchronizer().gather(rhs, 0);
// // }
// //}
// //
// ///* -------------------------------------------------------------------------- */
// //void SolverMumps::solve() {
// // AKANTU_DEBUG_IN();
// //
// // if(parallel_method == SolverMumpsOptions::_fully_distributed)
// // mumps_data.a_loc = matrix->getA().values;
// // else
// // if(prank == 0) {
// // mumps_data.a = matrix->getA().values;
// // }
// //
// // if(prank == 0) {
// // mumps_data.rhs = rhs->values;
// // }
// //
// // /// Default centralized dense second member
// // icntl(20) = 0;
// // icntl(21) = 0;
// //
// // mumps_data.job = _smj_factorize_solve; //solve
// // dmumps_c(&mumps_data);
// //
// // AKANTU_DEBUG_ASSERT(info(1) != -10, "Singular matrix");
// // AKANTU_DEBUG_ASSERT(info(1) == 0,
// // "Error in mumps during solve process, check mumps user guide INFO(1) ="
// // << info(1));
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///* -------------------------------------------------------------------------- */
// //void SolverMumps::solve(Array<Real> & solution) {
// // AKANTU_DEBUG_IN();
// //
// // solve();
// //
// // if(prank == 0) {
// // matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
// // } else {
// // matrix->getDOFSynchronizer().scatter(solution, 0);
// // }
// //
// // AKANTU_DEBUG_OUT();
// //}
__END_AKANTU__
diff --git a/src/solver/solver_petsc.hh b/src/solver/solver_petsc.hh
index 5016c98f7..8a2c04728 100644
--- a/src/solver/solver_petsc.hh
+++ b/src/solver/solver_petsc.hh
@@ -1,166 +1,167 @@
/**
* @file solver_petsc.hh
*
- # @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
+ * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
- * @date Mon Dec 13 10:48:06 2010
+ * @date creation: Tue May 13 2014
+ * @date last modification: Wed Oct 07 2015
*
* @brief Solver class interface for the petsc solver
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_PETSC_HH__
#define __AKANTU_SOLVER_PETSC_HH__
/* -------------------------------------------------------------------------- */
#include "solver.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class PETScSolverWrapper;
class SolverPETSc : public Solver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SolverPETSc(SparseMatrix & sparse_matrix,
const ID & id = "solver_petsc",
const MemoryID & memory_id = 0);
virtual ~SolverPETSc();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// create the solver context and set the matrices
virtual void initialize(SolverOptions & options = _solver_no_options);
virtual void setOperators();
virtual void setRHS(Array<Real> & rhs);
virtual void solve();
virtual void solve(Array<Real> & solution);
private:
/// clean the petsc data
virtual void destroyInternalData();
private:
/// specify if the petsc_data is initialized or not
bool is_petsc_data_initialized;
/// store the PETSc structures
PETScSolverWrapper * petsc_solver_wrapper;
};
// SolverPETSc(int argc, char *argv[]) : allocated_(false) {
// /*
// Set linear solver defaults for this problem (optional).
// - By extracting the KSP and PC contexts from the KSP context,
// we can then directly call any KSP and PC routines to set
// various options.
// - The following four statements are optional; all of these
// parameters could alternatively be specified at runtime via
// KSPSetFromOptions();
// */
// // ierr = KSPGetPC(ksp_,&pc);CHKERRCONTINUE(ierr);
// // ierr = PCSetType(pc,PCILU);CHKERRCONTINUE(ierr);
// // ierr = PCSetType(pc,PCJACOBI);CHKERRCONTINUE(ierr);
// ierr = KSPSetTolerances(ksp_,1.e-5,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRCONTINUE(ierr);
// }
// //! Overload operator() to solve system of linear equations
// sparse_vector_type operator()(const sparse_matrix_type& AA, const sparse_vector_type& bb);
// //! Overload operator() to obtain reaction vector
// sparse_vector_type operator()(const sparse_matrix_type& Kpf, const sparse_matrix_type& Kpp, const sparse_vector_type& Up);
// //! Overload operator() to obtain the addition two vectors
// sparse_vector_type operator()(const sparse_vector_type& aa, const sparse_vector_type& bb);
// value_type norm(const sparse_matrix_type& aa, Element_insertion_type it = Add_t);
// value_type norm(const sparse_vector_type& aa, Element_insertion_type it = Add_t);
// // NOTE: the destructor will return an error if it is called after MPI_Finalize is
// // called because it uses collect communication to free-up allocated memory.
// ~SolverPETSc() {
// static bool exit = false;
// if (!exit) {
// // add finalize PETSc function at exit
// atexit(finalize);
// exit = true;
// }
// if (allocated_) {
// PetscErrorCode ierr = MatDestroy(&A_);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&x_);CHKERRCONTINUE(ierr);
// ierr = KSPDestroy(&ksp_);CHKERRCONTINUE(ierr);
// }
// }
// /* from the PETSc library, these are the options that can be passed
// to the command line
// Options Database Keys
// -options_table - Calls PetscOptionsView()
// -options_left - Prints unused options that remain in the database
// -objects_left - Prints list of all objects that have not been freed
// -mpidump - Calls PetscMPIDump()
// -malloc_dump - Calls PetscMallocDump()
// -malloc_info - Prints total memory usage
// -malloc_log - Prints summary of memory usage
// Options Database Keys for Profiling
// -log_summary [filename] - Prints summary of flop and timing information to screen.
// If the filename is specified the summary is written to the file. See PetscLogView().
// -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
// -log_all [filename] - Logs extensive profiling information See PetscLogDump().
// -log [filename] - Logs basic profiline information See PetscLogDump().
// -log_sync - Log the synchronization in scatters, inner products and norms
// -log_mpe [filename] - Creates a logfile viewable by the utility Upshot/Nupshot (in MPICH distribution)
// }
// }
// };
__END_AKANTU__
#endif /* __AKANTU_SOLVER_PETSC_HH__ */
diff --git a/src/solver/sparse_matrix.cc b/src/solver/sparse_matrix.cc
index c2b3c78e6..f1817452d 100644
--- a/src/solver/sparse_matrix.cc
+++ b/src/solver/sparse_matrix.cc
@@ -1,625 +1,626 @@
/**
* @file sparse_matrix.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Mon Nov 16 2015
*
* @brief implementation of the SparseMatrix class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <fstream>
/* -------------------------------------------------------------------------- */
#include "sparse_matrix.hh"
#include "static_communicator.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SparseMatrix::SparseMatrix(UInt size,
const SparseMatrixType & sparse_matrix_type,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
sparse_matrix_type(sparse_matrix_type),
size(size),
nb_non_zero(0),
irn(0,1,"irn"), jcn(0,1,"jcn"), a(0,1,"A"), offset(1) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
nb_proc = comm.getNbProc();
dof_synchronizer = NULL;
irn_save = NULL;
jcn_save = NULL;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseMatrix::SparseMatrix(const SparseMatrix & matrix,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
sparse_matrix_type(matrix.sparse_matrix_type),
size(matrix.size),
nb_proc(matrix.nb_proc),
nb_non_zero(matrix.nb_non_zero),
irn(matrix.irn, true), jcn(matrix.jcn, true), a(matrix.getA(), true),
irn_jcn_k(matrix.irn_jcn_k), offset(1) {
AKANTU_DEBUG_IN();
size_save = 0;
irn_save = NULL;
jcn_save = NULL;
dof_synchronizer = matrix.dof_synchronizer;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseMatrix::~SparseMatrix() {
AKANTU_DEBUG_IN();
// if (irn_jcn_to_k) delete irn_jcn_to_k;
if(irn_save) delete irn_save;
if(jcn_save) delete jcn_save;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom) {
AKANTU_DEBUG_IN();
// if(irn_jcn_to_k) delete irn_jcn_to_k;
// irn_jcn_to_k = new std::map<std::pair<UInt, UInt>, UInt>;
clearProfile();
this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
coordinate_list_map::iterator irn_jcn_k_it;
Int * eq_nb_val = dof_synchronizer.getGlobalDOFEquationNumbers().storage();
Mesh::type_iterator it = mesh.firstType(mesh.getSpatialDimension(), _not_ghost, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType (mesh.getSpatialDimension(), _not_ghost, _ek_not_defined);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
UInt * conn_val = mesh.getConnectivity(*it, _not_ghost).storage();
Int * local_eq_nb_val = new Int[nb_degree_of_freedom * nb_nodes_per_element];
for (UInt e = 0; e < nb_element; ++e) {
Int * tmp_local_eq_nb_val = local_eq_nb_val;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
UInt n = conn_val[i];
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
*tmp_local_eq_nb_val++ = eq_nb_val[n * nb_degree_of_freedom + d];
}
// memcpy(tmp_local_eq_nb_val, eq_nb_val + n * nb_degree_of_freedom, nb_degree_of_freedom * sizeof(Int));
// tmp_local_eq_nb_val += nb_degree_of_freedom;
}
for (UInt i = 0; i < size_mat; ++i) {
UInt c_irn = local_eq_nb_val[i];
if(c_irn < this->size) {
UInt j_start = (sparse_matrix_type == _symmetric) ? i : 0;
for (UInt j = j_start; j < size_mat; ++j) {
UInt c_jcn = local_eq_nb_val[j];
if(c_jcn < this->size) {
KeyCOO irn_jcn = key(c_irn, c_jcn);
irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
if (irn_jcn_k_it == irn_jcn_k.end()) {
irn_jcn_k[irn_jcn] = nb_non_zero;
irn.push_back(c_irn + 1);
jcn.push_back(c_jcn + 1);
nb_non_zero++;
}
}
}
}
}
conn_val += nb_nodes_per_element;
}
delete [] local_eq_nb_val;
}
/// for pbc @todo correct it for parallel
if(StaticCommunicator::getStaticCommunicator().getNbProc() == 1) {
for (UInt i = 0; i < size; ++i) {
KeyCOO irn_jcn = key(i, i);
irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
if(irn_jcn_k_it == irn_jcn_k.end()) {
irn_jcn_k[irn_jcn] = nb_non_zero;
irn.push_back(i + 1);
jcn.push_back(i + 1);
nb_non_zero++;
}
}
}
else { // for pbc in parallel
for (UInt n=0; n<mesh.getNbNodes(); ++n) {
for (UInt d=0; d<nb_degree_of_freedom; ++d) {
if (mesh.isLocalOrMasterNode(n)) {
UInt i = mesh.getNodeGlobalId(n) * nb_degree_of_freedom + d;
KeyCOO irn_jcn = key(i, i);
irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
if(irn_jcn_k_it == irn_jcn_k.end()) {
irn_jcn_k[irn_jcn] = nb_non_zero;
irn.push_back(i + 1);
jcn.push_back(i + 1);
nb_non_zero++;
}
}
}
}
}
a.resize(nb_non_zero);
AKANTU_DEBUG_OUT();
}
///* -------------------------------------------------------------------------- */
//void SparseMatrix::applyBoundaryNormal(Array<bool> & boundary_normal, Array<Real> & EulerAngles, Array<Real> & rhs, const Array<Real> & matrix, Array<Real> & rhs_rotated) {
// AKANTU_DEBUG_IN();
//
//
// const UInt dim = nb_degree_of_freedom;
// const UInt nb_nodes = boundary_normal.getSize();
// Matrix<Real> Ti(dim, dim);
// Matrix<Real> Tj(dim, dim);
// Matrix<Real> small_matrix(dim, dim);
// Matrix<Real> Ti_small_matrix(dim, dim);
// Matrix<Real> Ti_small_matrix_Tj(dim, dim);
// Matrix<Real> small_rhs(dim, 1);
// Matrix<Real> Ti_small_rhs(dim, 1);
// //Transformation matrix based on euler angles X_1Y_2Z_3
//
// const DOFSynchronizer::GlobalEquationNumberMap & local_eq_num_to_global = dof_synchronizer->getGlobalEquationNumberToLocal();
//
// Int * irn_val = irn.storage();
// Int * jcn_val = jcn.storage();
// Int * eq_nb_val = dof_synchronizer->getGlobalDOFEquationNumbers().storage();
// Int * eq_nb_rhs_val = dof_synchronizer->getLocalDOFEquationNumbers().storage();
//
// Array<bool> * nodes_rotated = new Array<bool > (nb_nodes, dim, "nodes_rotated");
// nodes_rotated->clear();
//
// Array<Int> * local_eq_nb_val_node_i = new Array<Int > (1, nb_degree_of_freedom, "local_eq_nb_val_node_i");
// local_eq_nb_val_node_i->clear();
// Array<Int> * local_eq_nb_val_node_j = new Array<Int > (1, nb_degree_of_freedom, "local_eq_nb_val_node_j");
// local_eq_nb_val_node_j->clear();
//
// for (UInt i = 0; i < nb_non_zero; ++i) {
// UInt ni = local_eq_num_to_global.find(*irn_val - 1)->second;
// UInt node_i = (ni - ni % nb_degree_of_freedom) / nb_degree_of_freedom;
// UInt nj = local_eq_num_to_global.find(*jcn_val - 1)->second;
// UInt node_j = (nj - nj % nb_degree_of_freedom) / nb_degree_of_freedom;
// bool constrain_ij = false;
// for (UInt j = 0; j < dim; j++){
// if ( (boundary_normal(node_i, j) || boundary_normal(node_j, j)) ) {
// constrain_ij = true;
// break;
// }
// }
//
// if(constrain_ij){
// if(dim==2){
// Real Theta=EulerAngles(node_i,0);
// Ti(0,0)=cos(Theta);
// Ti(0,1)=-sin(Theta);
// Ti(1,1)=cos(Theta);
// Ti(1,0)=sin(Theta);
//
// Theta=EulerAngles(node_j,0);
// Tj(0,0)=cos(Theta);
// Tj(0,1)=-sin(Theta);
// Tj(1,1)=cos(Theta);
// Tj(1,0)=sin(Theta);
// }
// else if(dim==3){
// Real Theta_x=EulerAngles(node_i,0);
// Real Theta_y=EulerAngles(node_i,1);
// Real Theta_z=EulerAngles(node_i,2);
//
// Ti(0,0)=cos(Theta_y)*cos(Theta_z);
// Ti(0,1)=-cos(Theta_y)*sin(Theta_z);
// Ti(0,2)=sin(Theta_y);
// Ti(1,0)=cos(Theta_x)*sin(Theta_z)+cos(Theta_z)*sin(Theta_x)*sin(Theta_y);
// Ti(1,1)=cos(Theta_x)*cos(Theta_z)-sin(Theta_x)*sin(Theta_y)*sin(Theta_z);
// Ti(1,2)=-cos(Theta_y)*sin(Theta_x);
// Ti(2,0)=sin(Theta_x)*sin(Theta_z)-cos(Theta_x)*cos(Theta_z)*sin(Theta_y);
// Ti(2,1)=cos(Theta_z)*sin(Theta_x)+cos(Theta_x)*sin(Theta_y)*sin(Theta_z);
// Ti(2,2)=cos(Theta_x)*cos(Theta_y);
//
// Theta_x=EulerAngles(node_j,0);
// Theta_y=EulerAngles(node_j,1);
// Theta_z=EulerAngles(node_j,2);
//
// Tj(0,0)=cos(Theta_y)*cos(Theta_z);
// Tj(0,1)=-cos(Theta_y)*sin(Theta_z);
// Tj(0,2)=sin(Theta_y);
// Tj(1,0)=cos(Theta_x)*sin(Theta_z)+cos(Theta_z)*sin(Theta_x)*sin(Theta_y);
// Tj(1,1)=cos(Theta_x)*cos(Theta_z)-sin(Theta_x)*sin(Theta_y)*sin(Theta_z);
// Tj(1,2)=-cos(Theta_y)*sin(Theta_x);
// Tj(2,0)=sin(Theta_x)*sin(Theta_z)-cos(Theta_x)*cos(Theta_z)*sin(Theta_y);
// Tj(2,1)=cos(Theta_z)*sin(Theta_x)+cos(Theta_x)*sin(Theta_y)*sin(Theta_z);
// Tj(2,2)=cos(Theta_x)*cos(Theta_y);
// }
// for (UInt j = 0; j < nb_degree_of_freedom; ++j){
// local_eq_nb_val_node_i->storage()[j] = eq_nb_val[node_i * nb_degree_of_freedom + j];
// local_eq_nb_val_node_j->storage()[j] = eq_nb_val[node_j * nb_degree_of_freedom + j];
// }
// for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
// for (UInt k = 0; k < nb_degree_of_freedom; ++k) {
// KeyCOO jcn_irn = key(local_eq_nb_val_node_i->storage()[j], local_eq_nb_val_node_j->storage()[k]);
// coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
// small_matrix(j, k) = matrix.storage()[irn_jcn_k_it->second];
// }
// small_rhs(j,0)=rhs.storage()[eq_nb_rhs_val[node_i*dim+j]];
// }
//
// Ti_small_matrix.mul < false, false > (Ti, small_matrix);
// Ti_small_matrix_Tj.mul < false, true> (Ti_small_matrix, Tj);
// Ti_small_rhs.mul<false, false>(Ti, small_rhs);
//
// /*for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
// for (UInt k = 0; k < nb_degree_of_freedom; ++k) {
// KeyCOO jcn_irn = key(local_eq_nb_val_node_i->storage()[j], local_eq_nb_val_node_j->storage()[k]);
// coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
// a.storage()[irn_jcn_k_it->second] = T_small_matrix_T(j,k);
// }
// if(node_constrain==node_i && !( nodes_rotated->storage()[node_i]))
// rhs.storage()[eq_nb_rhs_val[node_i*dim+j]]=T_small_rhs(j,0);
// }*/
// KeyCOO jcn_irn = key(ni, nj);
// coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
// a.storage()[irn_jcn_k_it->second] = Ti_small_matrix_Tj(ni % nb_degree_of_freedom, nj % nb_degree_of_freedom);
// //this->saveMatrix("stiffness_partial.out");
// if (!(nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]])) {
// rhs_rotated.storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = Ti_small_rhs(ni % nb_degree_of_freedom, 0);
// nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = true;
// }
// }
// else{
// if (!(nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]])) {
// rhs_rotated.storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = rhs.storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]];
// nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = true;
// }
// }
// irn_val++;
// jcn_val++;
// }
//
// delete local_eq_nb_val_node_i;
// delete local_eq_nb_val_node_j;
// delete nodes_rotated;
// this->saveMatrix("stiffness_rotated.out");
// applyBoundary(boundary_normal);
//
// /*Real norm = 0;
// UInt n_zeros = 0;
// for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
// norm += Normal.storage()[j] * Normal.storage()[j];
// if (std::abs(Normal.storage()[j]) < Math::getTolerance())
// n_zeros++;
// }
// norm = sqrt(norm);
// AKANTU_DEBUG_ASSERT(norm > Math::getTolerance(), "The normal is not right");
// for (UInt j = 0; j < nb_degree_of_freedom; ++j)
// Normal.storage()[j] /= norm;
//
// if (n_zeros == nb_degree_of_freedom - 1) {
// UInt nb_nodes = boundary_normal.getSize();
// for (UInt i = 0; i < nb_nodes; ++i) {
// if (boundary_normal(i, 0))
// for (UInt j = 0; j < nb_degree_of_freedom; ++j)
// boundary(i, j) += Normal(0, j);
// }
// } else {
//
// const DOFSynchronizer::GlobalEquationNumberMap & local_eq_num_to_global = dof_synchronizer->getGlobalEquationNumberToLocal();
//
// Int * irn_val = irn.storage();
// Int * eq_nb_val = dof_synchronizer->getGlobalDOFEquationNumbers().storage();
// Array<Int> * local_eq_nb_val = new Array<Int > (1, nb_degree_of_freedom, "local_eq_nb_val");
// local_eq_nb_val->clear();
// UInt nb_nodes = boundary_normal.getSize();
// Array<bool> * node_set = new Array<bool > (nb_nodes, 1, "node_set");
// node_set->clear();
//
// for (UInt i = 0; i < nb_non_zero; ++i) {
// UInt ni = local_eq_num_to_global.find(*irn_val - 1)->second;
// UInt node_i = (ni - ni % nb_degree_of_freedom) / nb_degree_of_freedom;
// if (boundary_normal.storage()[ni]) {
// if ((!number.storage()[ni]) && (!node_set->storage()[node_i])) {
// UInt normal_component_i = ni % nb_degree_of_freedom; //DOF of node node_i to be removed
// if (std::abs(Normal.storage()[normal_component_i]) > Math::getTolerance()) {
// for (UInt j = 0; j < nb_degree_of_freedom; ++j)
// local_eq_nb_val->storage()[j] = eq_nb_val[node_i * nb_degree_of_freedom + j];
//
// UInt DOF_remove = local_eq_nb_val->storage()[normal_component_i];
// KeyCOO jcn_irn = key(DOF_remove, DOF_remove);
// coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
//
// Real aii = a.storage()[irn_jcn_k_it->second];
// Real normal_constant = (1 - aii) / (Normal.storage()[normal_component_i] * Normal.storage()[normal_component_i]);
//
// for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
// UInt line_j = local_eq_nb_val->storage()[j];
// for (UInt k = 0; k < nb_degree_of_freedom; ++k) {
// UInt column_k = local_eq_nb_val->storage()[k];
// jcn_irn = key(line_j, column_k);
// if ((line_j == column_k) && (line_j == DOF_remove))
// a.storage()[irn_jcn_k_it->second] = 1;
// else
// a.storage()[irn_jcn_k_it->second] += Normal.storage()[j] * Normal.storage()[k] * normal_constant;
// }
// }
//
// number.storage()[ni]++;
// node_set->storage()[node_i] = false;
// }
// }
// }
// irn_val++;
// }
//
// delete local_eq_nb_val;
// delete node_set;
// }*/
// AKANTU_DEBUG_OUT();
//}
/* -------------------------------------------------------------------------- */
void SparseMatrix::applyBoundary(const Array<bool> & boundary, Real block_val) {
AKANTU_DEBUG_IN();
const DOFSynchronizer::GlobalEquationNumberMap & local_eq_num_to_global = dof_synchronizer->getGlobalEquationNumberToLocal();
Int * irn_val = irn.storage();
Int * jcn_val = jcn.storage();
Real * a_val = a.storage();
for (UInt i = 0; i < nb_non_zero; ++i) {
/// @todo fix this hack, put here for the implementation of augmented
/// lagrangian contact
if (local_eq_num_to_global.find(*irn_val - 1) == local_eq_num_to_global.end())
continue;
if (local_eq_num_to_global.find(*jcn_val - 1) == local_eq_num_to_global.end())
continue;
UInt ni = local_eq_num_to_global.find(*irn_val - 1)->second;
UInt nj = local_eq_num_to_global.find(*jcn_val - 1)->second;
if(boundary.storage()[ni] || boundary.storage()[nj]) {
if (*irn_val != *jcn_val) {
*a_val = 0;
} else {
if(dof_synchronizer->getDOFTypes()(ni) >= 0) {
*a_val = 0;
} else {
*a_val = block_val;
}
}
}
irn_val++; jcn_val++; a_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::saveProfile(const std::string & filename) const {
AKANTU_DEBUG_IN();
std::ofstream outfile;
outfile.open(filename.c_str());
outfile << "%%MatrixMarket matrix coordinate pattern";
if(sparse_matrix_type == _symmetric) outfile << " symmetric";
else outfile << " general";
outfile << std::endl;
UInt m = size;
outfile << m << " " << m << " " << nb_non_zero << std::endl;
for (UInt i = 0; i < nb_non_zero; ++i) {
outfile << irn.storage()[i] << " " << jcn.storage()[i] << " 1" << std::endl;
}
outfile.close();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::saveMatrix(const std::string & filename) const {
AKANTU_DEBUG_IN();
std::ofstream outfile;
outfile.precision(std::numeric_limits<Real>::digits10);
outfile.open(filename.c_str());
outfile << "%%MatrixMarket matrix coordinate real";
if(sparse_matrix_type == _symmetric) outfile << " symmetric";
else outfile << " general";
outfile << std::endl;
outfile << size << " " << size << " " << nb_non_zero << std::endl;
for (UInt i = 0; i < nb_non_zero; ++i) {
outfile << irn(i) << " " << jcn(i) << " " << a(i) << std::endl;
}
outfile.close();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat) {
AKANTU_DEBUG_IN();
// AKANTU_DEBUG_ASSERT((vect.getSize()*vect.getNbComponent() == mat.getSize()) &&
// (vect.getNbComponent() == mat.getNbDegreOfFreedom()),
// "The size of the matrix and the vector do not match");
const SparseMatrixType & sparse_matrix_type = mat.getSparseMatrixType();
DOFSynchronizer * dof_synchronizer = mat.getDOFSynchronizerPointer();
UInt nb_non_zero = mat.getNbNonZero();
Real * tmp = new Real [vect.getNbComponent() * vect.getSize()];
std::fill_n(tmp, vect.getNbComponent() * vect.getSize(), 0);
Int * i_val = mat.getIRN().storage();
Int * j_val = mat.getJCN().storage();
Real * a_val = mat.getA().storage();
Real * vect_val = vect.storage();
for (UInt k = 0; k < nb_non_zero; ++k) {
UInt i = *(i_val++);
UInt j = *(j_val++);
Real a = *(a_val++);
UInt local_i = i - 1;
UInt local_j = j - 1;
if(dof_synchronizer) {
local_i = dof_synchronizer->getDOFLocalID(local_i);
local_j = dof_synchronizer->getDOFLocalID(local_j);
}
tmp[local_i] += a * vect_val[local_j];
if((sparse_matrix_type == _symmetric) && (local_i != local_j))
tmp[local_j] += a * vect_val[local_i];
}
memcpy(vect_val, tmp, vect.getNbComponent() * vect.getSize() * sizeof(Real));
delete [] tmp;
if(dof_synchronizer)
dof_synchronizer->reduceSynchronize<AddOperation>(vect);
AKANTU_DEBUG_OUT();
return vect;
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::copyContent(const SparseMatrix & matrix) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
"The to matrix don't have the same profiles");
memcpy(a.storage(), matrix.getA().storage(), nb_non_zero * sizeof(Real));
AKANTU_DEBUG_OUT();
}
///* -------------------------------------------------------------------------- */
//void SparseMatrix::copyProfile(const SparseMatrix & matrix) {
// AKANTU_DEBUG_IN();
// irn = matrix.irn;
// jcn = matrix.jcn;
// nb_non_zero = matrix.nb_non_zero;
// irn_jcn_k = matrix.irn_jcn_k;
// a.resize(nb_non_zero);
// AKANTU_DEBUG_OUT();
//}
/* -------------------------------------------------------------------------- */
void SparseMatrix::add(const SparseMatrix & matrix, Real alpha) {
AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
"The to matrix don't have the same profiles");
Real * a_val = a.storage();
Real * b_val = matrix.a.storage();
for (UInt n = 0; n < nb_non_zero; ++n) {
*a_val++ += alpha * *b_val++;
}
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::lump(Array<Real> & lumped) {
AKANTU_DEBUG_IN();
UInt vect_size = size / lumped.getNbComponent();
if(dof_synchronizer) vect_size = dof_synchronizer->getNbDOFs() / lumped.getNbComponent();
lumped.resize(vect_size);
lumped.clear();
Int * i_val = irn.storage();
Int * j_val = jcn.storage();
Real * a_val = a.storage();
Real * vect_val = lumped.storage();
for (UInt k = 0; k < nb_non_zero; ++k) {
UInt i = *(i_val++);
UInt j = *(j_val++);
Real a = *(a_val++);
UInt local_i = i - 1;
UInt local_j = j - 1;
if(dof_synchronizer) {
local_i = dof_synchronizer->getDOFLocalID(local_i);
local_j = dof_synchronizer->getDOFLocalID(local_j);
}
vect_val[local_i] += a;
if(sparse_matrix_type == _symmetric && (i != j))
vect_val[local_j] += a;
}
if(dof_synchronizer)
dof_synchronizer->reduceSynchronize<AddOperation>(lumped);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::clear() {
memset(a.storage(), 0, nb_non_zero*sizeof(Real));
}
__END_AKANTU__
diff --git a/src/solver/sparse_matrix.hh b/src/solver/sparse_matrix.hh
index 99bdf4966..c77fce518 100644
--- a/src/solver/sparse_matrix.hh
+++ b/src/solver/sparse_matrix.hh
@@ -1,239 +1,240 @@
/**
* @file sparse_matrix.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Fri Oct 16 2015
*
* @brief sparse matrix storage class (distributed assembled matrix)
* This is a COO format (Coordinate List)
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SPARSE_MATRIX_HH__
#define __AKANTU_SPARSE_MATRIX_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class DOFSynchronizer;
class SparseMatrix : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SparseMatrix(UInt size, const SparseMatrixType & sparse_matrix_type,
const ID & id = "sparse_matrix", const MemoryID & memory_id = 0);
SparseMatrix(const SparseMatrix & matrix, const ID & id = "sparse_matrix",
const MemoryID & memory_id = 0);
virtual ~SparseMatrix();
typedef std::pair<UInt, UInt> KeyCOO;
typedef unordered_map<KeyCOO, UInt>::type coordinate_list_map;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// remove the existing profile
inline void clearProfile();
/// add a non-zero element
virtual UInt addToProfile(UInt i, UInt j);
/// set the matrix to 0
virtual void clear();
/// assemble a local matrix in the sparse one
inline void addToMatrix(UInt i, UInt j, Real value);
/// set the size of the matrix
void resize(UInt size) { this->size = size; }
virtual void buildProfile(const Mesh & mesh,
const DOFSynchronizer & dof_synchronizer,
UInt nb_degree_of_freedom);
/// modify the matrix to "remove" the blocked dof
virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
// /// modify the matrix to "remove" the blocked dof
// void applyBoundaryNormal(Array<bool> & boundary_normal, Array<Real> &
// EulerAngles, Array<Real> & rhs, const Array<Real> & matrix, Array<Real> &
// rhs_rotated);
/// save the profil in a file using the MatrixMarket file format
virtual void saveProfile(const std::string & filename) const;
/// save the matrix in a file using the MatrixMarket file format
virtual void saveMatrix(const std::string & filename) const;
/// copy assuming the profile are the same
virtual void copyContent(const SparseMatrix & matrix);
/// copy profile
// void copyProfile(const SparseMatrix & matrix);
/// add matrix assuming the profile are the same
virtual void add(const SparseMatrix & matrix, Real alpha);
/// diagonal lumping
virtual void lump(Array<Real> & lumped);
/// function to print the contain of the class
// virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
inline KeyCOO key(UInt i, UInt j) const {
if (sparse_matrix_type == _symmetric && (i > j))
return std::make_pair(j, i);
return std::make_pair(i, j);
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// return the values at potition i, j
inline Real operator()(UInt i, UInt j) const;
inline Real & operator()(UInt i, UInt j);
AKANTU_GET_MACRO(IRN, irn, const Array<Int> &);
AKANTU_GET_MACRO(JCN, jcn, const Array<Int> &);
AKANTU_GET_MACRO(A, a, const Array<Real> &);
AKANTU_GET_MACRO(NbNonZero, nb_non_zero, UInt);
AKANTU_GET_MACRO(Size, size, UInt);
AKANTU_GET_MACRO(SparseMatrixType, sparse_matrix_type,
const SparseMatrixType &);
AKANTU_GET_MACRO(Offset, offset, UInt);
const DOFSynchronizer & getDOFSynchronizer() const {
AKANTU_DEBUG_ASSERT(dof_synchronizer != NULL,
"DOFSynchronizer not initialized in the SparseMatrix!");
return *dof_synchronizer;
}
DOFSynchronizer & getDOFSynchronizer() {
AKANTU_DEBUG_ASSERT(dof_synchronizer != NULL,
"DOFSynchronizer not initialized in the SparseMatrix!");
return *dof_synchronizer;
}
private:
AKANTU_GET_MACRO(DOFSynchronizerPointer, dof_synchronizer, DOFSynchronizer *);
friend Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// id of the SparseMatrix
ID id;
/// sparce matrix type
SparseMatrixType sparse_matrix_type;
/// Mesh corresponding to the profile
// const Mesh * mesh;
/// Size of the matrix
UInt size;
/// number of processors
UInt nb_proc;
/// number of non zero element
UInt nb_non_zero;
/// row indexes
Array<Int> irn;
/// column indexes
Array<Int> jcn;
/// values : A[k] = Matrix[irn[k]][jcn[k]]
Array<Real> a;
/// saved row indexes
Array<Int> * irn_save;
/// saved column indexes
Array<Int> * jcn_save;
/// saved size
UInt size_save;
/// information to know where to assemble an element in a global sparse matrix
// ElementTypeMapArray<UInt> element_to_sparse_profile;
/* map for (i,j) -> k correspondence \warning std::map are slow
* \todo improve with hash_map (non standard in stl) or unordered_map (boost
* or C++0x)
*/
coordinate_list_map irn_jcn_k;
DOFSynchronizer * dof_synchronizer;
// std::map<std::pair<UInt, UInt>, UInt> * irn_jcn_to_k;
/// offset to inidcate whether row and column indices start at 0 (C/C++) or 1
/// (Fortran)
UInt offset;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_INCLUDE_INLINE_IMPL)
#include "sparse_matrix_inline_impl.cc"
#endif
// /// standard output stream operator
// inline std::ostream & operator <<(std::ostream & stream, const SparseMatrix &
// _this)
// {
// _this.printself(stream);
// return stream;
// }
Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat);
__END_AKANTU__
#endif /* __AKANTU_SPARSE_MATRIX_HH__ */
diff --git a/src/solver/sparse_matrix_inline_impl.cc b/src/solver/sparse_matrix_inline_impl.cc
index dfaf5baa1..5e9385d0e 100644
--- a/src/solver/sparse_matrix_inline_impl.cc
+++ b/src/solver/sparse_matrix_inline_impl.cc
@@ -1,141 +1,142 @@
/**
* @file sparse_matrix_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief implementation of inline methods of the SparseMatrix class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline UInt SparseMatrix::addToProfile(UInt i, UInt j) {
KeyCOO jcn_irn = key(i, j);
coordinate_list_map::iterator it = irn_jcn_k.find(jcn_irn);
if (!(it == irn_jcn_k.end()))
return it->second;
// AKANTU_DEBUG_ASSERT(irn_jcn_k.find(jcn_irn) == irn_jcn_k.end(),
// "Couple (i,j) = (" << i << "," << j << ") already in the profile");
irn.push_back(i + 1);
jcn.push_back(j + 1);
// a.resize(a.getSize() + 1);
Real zero = 0;
a.push_back(zero);
irn_jcn_k[jcn_irn] = nb_non_zero;
nb_non_zero++;
return nb_non_zero - 1;
}
/* -------------------------------------------------------------------------- */
inline void SparseMatrix::clearProfile() {
irn_jcn_k.clear();
irn.resize(0);
jcn.resize(0);
a.resize(0);
nb_non_zero = 0;
}
/* -------------------------------------------------------------------------- */
inline void SparseMatrix::addToMatrix(UInt i, UInt j, Real value) {
KeyCOO jcn_irn = key(i, j);
coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
AKANTU_DEBUG_ASSERT(irn_jcn_k_it != irn_jcn_k.end(),
"Couple (i,j) = (" << i << "," << j << ") does not exist in the profile");
a.storage()[irn_jcn_k_it->second] += value;
}
/* -------------------------------------------------------------------------- */
inline Real SparseMatrix::operator()(UInt i, UInt j) const {
KeyCOO jcn_irn = key(i, j);
coordinate_list_map::const_iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
if(irn_jcn_k_it == irn_jcn_k.end()) return 0;
return a.storage()[irn_jcn_k_it->second];
}
/* -------------------------------------------------------------------------- */
inline Real & SparseMatrix::operator()(UInt i, UInt j) {
KeyCOO jcn_irn = key(i, j);
coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
AKANTU_DEBUG_ASSERT(irn_jcn_k_it != irn_jcn_k.end(),
"Couple (i,j) = (" << i << "," << j << ") does not exist in the profile");
return a.storage()[irn_jcn_k_it->second];
}
/* -------------------------------------------------------------------------- */
// inline void SparseMatrix::addToMatrixSym(const Array<Real> & local_matrix,
// const Element & element) {
// AKANTU_DEBUG_ASSERT(element_to_sparse_profile[element.type] != NULL,
// "No profile stored for this kind of element call first buildProfile()");
// UInt nb_values_per_elem = element_to_sparse_profile[element.type]->getNbComponent();
// UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(element.type);
// Real * mat_val = local_matrix.storage();
// UInt * elem_to_sparse_val = element_to_sparse_profile[element.type]->values + element.element * nb_values_per_elem;
// Real * a_val = a.storage();
// for (UInt j = 0; j < nb_nodes_per_element * nb_degree_of_freedom; ++j) {
// UInt i_end = (sparse_matrix_type == _symmetric) ? j + 1 :
// nb_nodes_per_element * nb_degree_of_freedom;
// for (UInt i = 0; i < i_end; ++i) {
// UInt k = *(elem_to_sparse_val++);
// a_val[k] += *(mat_val++);
// }
// }
// }
/* -------------------------------------------------------------------------- */
// inline void SparseMatrix::addToMatrix(Real * local_matrix,
// const Element & element,
// UInt nb_nodes_per_element) {
// AKANTU_DEBUG_ASSERT(element_to_sparse_profile[element.type] != NULL,
// "No profile stored for this kind of element call first buildProfile()");
// UInt nb_values_per_elem = element_to_sparse_profile[element.type]->getNbComponent();
// // UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(element.type);
// Real * mat_val = local_matrix;
// UInt * elem_to_sparse_val = element_to_sparse_profile[element.type]->values + element.element * nb_values_per_elem;
// Real * a_val = a.storage();
// for (UInt i = 0; i < nb_nodes_per_element * nb_degree_of_freedom; ++i) {
// UInt j_start = (sparse_matrix_type == _symmetric) ? i : 0;
// UInt elem_to_sparse_i = i * nb_nodes_per_element * nb_degree_of_freedom;
// for (UInt j = j_start; j < nb_nodes_per_element * nb_degree_of_freedom; ++j) {
// UInt k = elem_to_sparse_val[elem_to_sparse_i + j];
// a_val[k] += mat_val[elem_to_sparse_i + j];
// }
// }
// }
diff --git a/src/solver/static_solver.cc b/src/solver/static_solver.cc
index 9358381c5..6f5c43a9c 100644
--- a/src/solver/static_solver.cc
+++ b/src/solver/static_solver.cc
@@ -1,112 +1,116 @@
/**
* @file static_solver.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Jul 30 15:35:01 2014
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Mon Oct 13 2014
+ * @date last modification: Fri Oct 16 2015
*
* @brief implementation of the static solver
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "static_solver.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_PETSC
#include <petscsys.h>
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
StaticSolver::StaticSolver() : CommunicatorEventHandler(), is_initialized(false) {
StaticCommunicator::getStaticCommunicator().registerEventHandler(*this);
}
/* -------------------------------------------------------------------------- */
StaticSolver::~StaticSolver() {
--this->nb_references;
if(this->nb_references == 0) {
StaticCommunicator::getStaticCommunicator().unregisterEventHandler(*this);
delete this->static_solver;
}
}
/* -------------------------------------------------------------------------- */
StaticSolver & StaticSolver::getStaticSolver() {
if(nb_references == 0)
static_solver = new StaticSolver();
++nb_references;
return *static_solver;
}
#ifdef AKANTU_USE_PETSC
#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
static PetscErrorCode PETScErrorHandler(MPI_Comm,
int line, const char * dir, const char *file,
PetscErrorCode number,
PetscErrorType type,
const char *message,
void *) {
AKANTU_DEBUG_ERROR("An error occured in PETSc in file \"" << file << ":" << line << "\" - PetscErrorCode "<< number << " - \""<< message << "\"");
}
#else
static PetscErrorCode PETScErrorHandler(MPI_Comm,
int line, const char * func, const char * dir, const char *file,
PetscErrorCode number,
PetscErrorType type,
const char *message,
void *) {
AKANTU_DEBUG_ERROR("An error occured in PETSc in file \"" << file << ":" << line << "\" - PetscErrorCode "<< number << " - \""<< message << "\"");
}
#endif
#endif
/* -------------------------------------------------------------------------- */
void StaticSolver::initialize(int & argc, char ** & argv) {
if (this->is_initialized) return;
// AKANTU_DEBUG_ASSERT(this->is_initialized != true, "The static solver has already been initialized");
#ifdef AKANTU_USE_PETSC
PetscErrorCode petsc_error = PetscInitialize(&argc, &argv, NULL, NULL);
if(petsc_error != 0) {
AKANTU_DEBUG_ERROR("An error occured while initializing Petsc (PetscErrorCode "<< petsc_error << ")");
}
PetscPushErrorHandler(PETScErrorHandler, NULL);
#endif
this->is_initialized = true;
}
/* -------------------------------------------------------------------------- */
void StaticSolver::finalize() {
ParentEventHandler::sendEvent(StaticSolverEvent::BeforeStaticSolverDestroyEvent());
AKANTU_DEBUG_ASSERT(this->is_initialized == true, "The static solver has not been initialized");
#ifdef AKANTU_USE_PETSC
PetscFinalize();
#endif
this->is_initialized = false;
}
__END_AKANTU__
diff --git a/src/solver/static_solver.hh b/src/solver/static_solver.hh
index 73923f221..2189728f4 100644
--- a/src/solver/static_solver.hh
+++ b/src/solver/static_solver.hh
@@ -1,108 +1,113 @@
/**
* @file static_solver.hh
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Jul 30 14:44:12 2014
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Oct 16 2015
*
* @brief Class handeling the initialization of external solvers
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "static_communicator.hh"
#ifndef __AKANTU_STATIC_SOLVER_HH__
#define __AKANTU_STATIC_SOLVER_HH__
__BEGIN_AKANTU__
namespace StaticSolverEvent {
struct BeforeStaticSolverDestroyEvent {
BeforeStaticSolverDestroyEvent() {}
};
}
class StaticSolverEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
virtual ~StaticSolverEventHandler() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
inline void sendEvent(const StaticSolverEvent::BeforeStaticSolverDestroyEvent & event) {
this->beforeStaticSolverDestroy();
}
template<class EventHandler> friend class EventHandlerManager;
/* ------------------------------------------------------------------------ */
/* Interface */
/* ------------------------------------------------------------------------ */
public:
virtual void beforeStaticSolverDestroy() {}
};
class StaticSolver : public CommunicatorEventHandler,
public EventHandlerManager<StaticSolverEventHandler> {
typedef EventHandlerManager<StaticSolverEventHandler> ParentEventHandler;
/* ------------------------------------------------------------------------ */
/* Constructors */
/* ------------------------------------------------------------------------ */
private:
StaticSolver();
public:
~StaticSolver();
/* ------------------------------------------------------------------------ */
/// get an instance to the static solver
static StaticSolver & getStaticSolver();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize what is needed for the compiled solver interfaces
void initialize(int & argc, char ** & argv);
/// finalize what is needed for the compiled solver interfaces
void finalize();
/* ------------------------------------------------------------------------ */
/* Members */
/* ------------------------------------------------------------------------ */
private:
bool is_initialized;
static UInt nb_references;
static StaticSolver * static_solver;
};
__END_AKANTU__
#endif /* __AKANTU_STATIC_SOLVER_HH__ */
diff --git a/src/synchronizer/communication_buffer.hh b/src/synchronizer/communication_buffer.hh
index 45323259a..0a6f61486 100644
--- a/src/synchronizer/communication_buffer.hh
+++ b/src/synchronizer/communication_buffer.hh
@@ -1,165 +1,166 @@
/**
* @file communication_buffer.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Apr 14 2011
- * @date last modification: Thu Mar 27 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Buffer for packing and unpacking data
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_array.hh"
#ifndef __AKANTU_COMMUNICATION_BUFFER_HH__
#define __AKANTU_COMMUNICATION_BUFFER_HH__
__BEGIN_AKANTU__
template<bool is_static = true>
class CommunicationBufferTemplated {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
CommunicationBufferTemplated(UInt size = 0) : buffer(size, 1) {
ptr_pack = buffer.storage();
ptr_unpack = buffer.storage();
};
virtual ~CommunicationBufferTemplated() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// reset to "empty"
inline void reset();
/// resize the internal buffer
inline void resize(UInt size);
/// clear buffer context
inline void clear();
private:
inline void packResize(UInt size);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
inline char * storage() { return buffer.storage(); };
/* ------------------------------------------------------------------------ */
/* Operators */
/* ------------------------------------------------------------------------ */
public:
/// printing tool
template <typename T> inline std::string extractStream(UInt packet_size);
/// packing data
template<typename T>
inline CommunicationBufferTemplated & operator<< (const T & to_pack);
template<typename T>
inline CommunicationBufferTemplated & operator<< (const Vector<T> & to_pack);
template<typename T>
inline CommunicationBufferTemplated & operator<< (const Matrix<T> & to_pack);
template<typename T>
inline CommunicationBufferTemplated & operator<< (const std::vector<T> & to_pack);
/// unpacking data
template<typename T>
inline CommunicationBufferTemplated & operator>> (T & to_unpack);
template<typename T>
inline CommunicationBufferTemplated & operator>> (Vector<T> & to_unpack);
template<typename T>
inline CommunicationBufferTemplated & operator>> (Matrix<T> & to_unpack);
template<typename T>
inline CommunicationBufferTemplated & operator>> (std::vector<T> & to_unpack);
inline CommunicationBufferTemplated & operator<< (const std::string & to_pack);
inline CommunicationBufferTemplated & operator>> (std::string & to_unpack);
private:
template<typename T>
inline void packIterable (T & to_pack);
template<typename T>
inline void unpackIterable (T & to_pack);
/* ------------------------------------------------------------------------ */
/* Accessor */
/* ------------------------------------------------------------------------ */
public:
/// return the size in bytes of the stored values
inline UInt getPackedSize(){ return ptr_pack - buffer.storage(); };
/// return the size in bytes of data left to be unpacked
inline UInt getLeftToUnpack(){ return buffer.getSize() - (ptr_unpack - buffer.storage()); };
/// return the global size allocated
inline UInt getSize(){ return buffer.getSize(); };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// current position for packing
char * ptr_pack;
/// current position for unpacking
char * ptr_unpack;
/// storing buffer
Array<char> buffer;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "communication_buffer_inline_impl.cc"
#endif
typedef CommunicationBufferTemplated<true> CommunicationBuffer;
typedef CommunicationBufferTemplated<false> DynamicCommunicationBuffer;
__END_AKANTU__
#endif /* __AKANTU_COMMUNICATION_BUFFER_HH__ */
diff --git a/src/synchronizer/communication_buffer_inline_impl.cc b/src/synchronizer/communication_buffer_inline_impl.cc
index 46adb62b3..8d60bd1ef 100644
--- a/src/synchronizer/communication_buffer_inline_impl.cc
+++ b/src/synchronizer/communication_buffer_inline_impl.cc
@@ -1,247 +1,248 @@
/**
* @file communication_buffer_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Apr 14 2011
- * @date last modification: Thu Mar 27 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief CommunicationBuffer inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
template<bool is_static>
inline void CommunicationBufferTemplated<is_static>::packResize(UInt size) {
if(!is_static) {
char * values = buffer.storage();
buffer.resize(buffer.getSize() + size);
ptr_pack = buffer.storage() + (ptr_pack - values);
ptr_unpack = buffer.storage() + (ptr_unpack - values);
}
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator<< (const T & to_pack) {
packResize(sizeof(T));
T * tmp = reinterpret_cast<T *>(ptr_pack);
AKANTU_DEBUG_ASSERT(buffer.storage() + buffer.getSize() >= ptr_pack + sizeof(T),
"Packing too much data in the CommunicationBufferTemplated");
*tmp = to_pack;
ptr_pack += sizeof(T);
return *this;
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator>> (T & to_unpack) {
T * tmp = reinterpret_cast<T *>(ptr_unpack);
to_unpack = *tmp;
ptr_unpack += sizeof(T);
return *this;
}
/* -------------------------------------------------------------------------- */
/* Specialization */
/* -------------------------------------------------------------------------- */
/**
* Vector
*/
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator<< (const Vector<T> & to_pack) {
UInt size = to_pack.size() * sizeof(T);
packResize(size);
AKANTU_DEBUG_ASSERT(buffer.storage() + buffer.getSize() >= ptr_pack + size,
"Packing too much data in the CommunicationBufferTemplated");
memcpy(ptr_pack, to_pack.storage(), size);
ptr_pack += size;
return *this;
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator>> (Vector<T> & to_unpack) {
UInt size = to_unpack.size() * sizeof(T);
memcpy(to_unpack.storage(), ptr_unpack, size);
ptr_unpack += size;
return *this;
}
/**
* Matrix
*/
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator<< (const Matrix<T> & to_pack) {
UInt size = to_pack.size() * sizeof(Real);
packResize(size);
AKANTU_DEBUG_ASSERT(buffer.storage() + buffer.getSize() >= ptr_pack + size,
"Packing too much data in the CommunicationBufferTemplated");
memcpy(ptr_pack, to_pack.storage(), size);
ptr_pack += size;
return *this;
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator>> (Matrix<T> & to_unpack) {
UInt size = to_unpack.size() * sizeof(Real);
memcpy(to_unpack.storage(), ptr_unpack, size);
ptr_unpack += size;
return *this;
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline void CommunicationBufferTemplated<is_static>::packIterable (T & to_pack) {
UInt size = to_pack.size();
operator<<(size);
typename T::const_iterator it = to_pack.begin();
typename T::const_iterator end = to_pack.end();
for(;it != end; ++it) operator<<(*it);
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline void CommunicationBufferTemplated<is_static>::unpackIterable (T & to_unpack) {
UInt size;
operator>>(size);
to_unpack.resize(size);
typename T::iterator it = to_unpack.begin();
typename T::iterator end = to_unpack.end();
for(;it != end; ++it) operator>>(*it);
}
/**
* std::vector<T>
*/
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator<< (const std::vector<T> & to_pack) {
packIterable(to_pack);
return *this;
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator>> (std::vector<T> & to_unpack) {
unpackIterable(to_unpack);
return *this;
}
/**
* std::string
*/
/* -------------------------------------------------------------------------- */
template<bool is_static>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator<< (const std::string & to_pack) {
packIterable(to_pack);
return *this;
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::operator>> (std::string & to_unpack) {
unpackIterable(to_unpack);
return *this;
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
template<typename T> inline std::string
CommunicationBufferTemplated<is_static>::extractStream(UInt block_size) {
std::stringstream str;
T * ptr = reinterpret_cast<T*>(buffer.storage());
UInt sz = buffer.getSize()/sizeof(T);
UInt sz_block = block_size/sizeof(T);
UInt n_block = 0;
for (UInt i = 0; i < sz; ++i) {
if (i% sz_block == 0) {
str << std::endl << n_block << " ";
++n_block;
}
str << *ptr << " ";
++ptr;
}
return str.str();
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
inline void CommunicationBufferTemplated<is_static>::resize(UInt size) {
if(!is_static) {
buffer.resize(0);
} else {
buffer.resize(size);
}
reset();
#ifndef AKANTU_NDEBUG
clear();
#endif
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
inline void CommunicationBufferTemplated<is_static>::clear() {
buffer.clear();
}
/* -------------------------------------------------------------------------- */
template<bool is_static>
inline void CommunicationBufferTemplated<is_static>::reset() {
ptr_pack = buffer.storage();
ptr_unpack = buffer.storage();
}
/* -------------------------------------------------------------------------- */
//template<bool is_static>
//inline CommunicationBufferTemplated<is_static> & CommunicationBufferTemplated<is_static>::packMeshData (const MeshData & to_pack, const ElementType & type) {
//UInt size = to_pack.size();
//operator<<(size);
//typename std::vector<T>::iterator it = to_pack.begin();
//typename std::vector<T>::iterator end = to_pack.end();
//for(;it != end; ++it) operator<<(*it);
//return *this;
//}
diff --git a/src/synchronizer/data_accessor.cc b/src/synchronizer/data_accessor.cc
index bb584f9b5..22086ebc8 100644
--- a/src/synchronizer/data_accessor.cc
+++ b/src/synchronizer/data_accessor.cc
@@ -1,51 +1,53 @@
/**
* @file data_accessor.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief data accessors constructor functions
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "data_accessor.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
DataAccessor::DataAccessor(){
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
DataAccessor::~DataAccessor() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/synchronizer/data_accessor.hh b/src/synchronizer/data_accessor.hh
index d9834cfe8..8a91c8447 100644
--- a/src/synchronizer/data_accessor.hh
+++ b/src/synchronizer/data_accessor.hh
@@ -1,268 +1,271 @@
/**
* @file data_accessor.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Wed Sep 01 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Interface of accessors for pack_unpack system
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DATA_ACCESSOR_HH__
#define __AKANTU_DATA_ACCESSOR_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "fe_engine.hh"
#include "communication_buffer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DataAccessor();
virtual ~DataAccessor();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/**
* @brief get the number of data to exchange for a given akantu::Element and a
* given akantu::SynchronizationTag
*/
virtual UInt getNbDataForElements(__attribute__((unused)) const Array<Element> & elements,
__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief get the number of data to exchange for a given degree of freedom and a
* given akantu::SynchronizationTag
*/
virtual UInt getNbDataForDOFs(__attribute__((unused)) const Array<UInt> & dofs,
__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief get the number of data to send for a given
* akantu::SynchronizationTag
*/
virtual UInt getNbDataToPack(__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief get the number of data to receive for a given
* akantu::SynchronizationTag
*/
virtual UInt getNbDataToUnpack(__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief pack the data for a given akantu::Element and a given
* akantu::SynchronizationTag
*/
virtual void packElementData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const Array<Element> & element,
__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief pack the data for a given index and a given
* akantu::SynchronizationTag
*/
virtual void packData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const UInt index,
__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief pack the data for the dofs and a given
* akantu::SynchronizationTag
*/
virtual void packDOFData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const Array<UInt> & dofs,
__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief unpack the data for a given akantu::Element and a given
* akantu::SynchronizationTag
*/
virtual void unpackElementData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const Array<Element> & element,
__attribute__((unused)) SynchronizationTag tag) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief unpack the data for a given index and a given
* akantu::SynchronizationTag
*/
virtual void unpackData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const UInt index,
__attribute__((unused)) SynchronizationTag tag) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief unpack the data for the dofs and a given
* akantu::SynchronizationTag
*/
virtual void unpackDOFData(__attribute__((unused)) CommunicationBuffer & buffer,
__attribute__((unused)) const Array<UInt> & dofs,
__attribute__((unused)) SynchronizationTag tag) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
public:
template<typename T>
static inline void packNodalDataHelper(const Array<T> & data,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const Mesh & mesh) {
packUnpackNodalDataHelper<T, true>(const_cast<Array<T> &>(data),
buffer,
elements,
mesh);
}
template<typename T>
static inline void unpackNodalDataHelper(Array<T> & data,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const Mesh & mesh) {
packUnpackNodalDataHelper<T, false>(data,
buffer,
elements,
mesh);
}
template<typename T, bool pack_helper>
static inline void packUnpackNodalDataHelper(Array<T> & data,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const Mesh & mesh);
template<typename T, bool pack_helper>
static inline void packUnpackElementalDataHelper(ElementTypeMapArray<T> & data_to_pack,
CommunicationBuffer & buffer,
const Array<Element> & element,
bool per_quadrature_point_data,
const FEEngine & fem);
template<typename T>
static inline void packElementalDataHelper(const ElementTypeMapArray<T> & data_to_pack,
CommunicationBuffer & buffer,
const Array<Element> & elements,
bool per_quadrature_point,
const FEEngine & fem) {
packUnpackElementalDataHelper<T, true>(const_cast<ElementTypeMapArray<T> &>(data_to_pack),
buffer,
elements,
per_quadrature_point,
fem);
}
template<typename T>
static inline void unpackElementalDataHelper(ElementTypeMapArray<T> & data_to_unpack,
CommunicationBuffer & buffer,
const Array<Element> & elements,
bool per_quadrature_point,
const FEEngine & fem) {
packUnpackElementalDataHelper<T, false>(data_to_unpack,
buffer,
elements,
per_quadrature_point,
fem);
}
template<typename T, bool pack_helper>
static inline void packUnpackDOFDataHelper(Array<T> & data,
CommunicationBuffer & buffer,
const Array<UInt> & dofs);
template<typename T>
static inline void packDOFDataHelper(const Array<T> & data_to_pack,
CommunicationBuffer & buffer,
const Array<UInt> & dofs) {
packUnpackDOFDataHelper<T, true>(const_cast<Array<T> &>(data_to_pack),
buffer,
dofs);
}
template<typename T>
static inline void unpackDOFDataHelper(Array<T> & data_to_unpack,
CommunicationBuffer & buffer,
const Array<UInt> & dofs) {
packUnpackDOFDataHelper<T, false>(data_to_unpack,
buffer,
dofs);
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "data_accessor_inline_impl.cc"
// /// standard output stream operator
// inline std::ostream & operator <<(std::ostream & stream, const DataAccessor & _this)
// {
// _this.printself(stream);
// return stream;
// }
__END_AKANTU__
#endif /* __AKANTU_DATA_ACCESSOR_HH__ */
diff --git a/src/synchronizer/data_accessor_inline_impl.cc b/src/synchronizer/data_accessor_inline_impl.cc
index dda6c4860..4c79b4d7b 100644
--- a/src/synchronizer/data_accessor_inline_impl.cc
+++ b/src/synchronizer/data_accessor_inline_impl.cc
@@ -1,125 +1,126 @@
/**
* @file data_accessor_inline_impl.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Sep 18 2013
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Implementation of the inline functions of the DataAccessor class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
template<typename T, bool pack_helper>
inline void DataAccessor::packUnpackNodalDataHelper(Array<T> & data,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const Mesh & mesh) {
UInt nb_component = data.getNbComponent();
UInt nb_nodes_per_element = 0;
ElementType current_element_type = _not_defined;
GhostType current_ghost_type = _casper;
UInt * conn = NULL;
Array<Element>::const_iterator<Element> it = elements.begin();
Array<Element>::const_iterator<Element> end = elements.end();
for (; it != end; ++it) {
const Element & el = *it;
if(el.type != current_element_type || el.ghost_type != current_ghost_type) {
current_element_type = el.type;
current_ghost_type = el.ghost_type;
conn = mesh.getConnectivity(el.type, el.ghost_type).storage();
nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
}
UInt el_offset = el.element * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt offset_conn = conn[el_offset + n];
Vector<T> data_vect(data.storage() + offset_conn * nb_component,
nb_component);
if(pack_helper)
buffer << data_vect;
else
buffer >> data_vect;
}
}
}
/* -------------------------------------------------------------------------- */
template<typename T, bool pack_helper>
inline void DataAccessor::packUnpackElementalDataHelper(ElementTypeMapArray<T> & data_to_pack,
CommunicationBuffer & buffer,
const Array<Element> & element,
bool per_quadrature_point_data,
const FEEngine & fem) {
ElementType current_element_type = _not_defined;
GhostType current_ghost_type = _casper;
UInt nb_quad_per_elem = 0;
UInt nb_component = 0;
Array<T> * vect = NULL;
Array<Element>::const_iterator<Element> it = element.begin();
Array<Element>::const_iterator<Element> end = element.end();
for (; it != end; ++it) {
const Element & el = *it;
if(el.type != current_element_type || el.ghost_type != current_ghost_type) {
current_element_type = el.type;
current_ghost_type = el.ghost_type;
vect = &data_to_pack(el.type, el.ghost_type);
if(per_quadrature_point_data)
nb_quad_per_elem = fem.getNbIntegrationPoints(el.type,
el.ghost_type);
else nb_quad_per_elem = 1;
nb_component = vect->getNbComponent();
}
Vector<T> data(vect->storage() + el.element * nb_component * nb_quad_per_elem,
nb_component * nb_quad_per_elem);
if(pack_helper)
buffer << data;
else
buffer >> data;
}
}
/* -------------------------------------------------------------------------- */
template<typename T, bool pack_helper>
inline void DataAccessor::packUnpackDOFDataHelper(Array<T> & data,
CommunicationBuffer & buffer,
const Array<UInt> & dofs) {
Array<UInt>::const_scalar_iterator it_dof = dofs.begin();
Array<UInt>::const_scalar_iterator end_dof = dofs.end();
T * data_ptr = data.storage();
for (; it_dof != end_dof; ++it_dof) {
if(pack_helper)
buffer << data_ptr[*it_dof];
else
buffer >> data_ptr[*it_dof];
}
}
diff --git a/src/synchronizer/distributed_synchronizer.cc b/src/synchronizer/distributed_synchronizer.cc
index 6e37e198f..81245e7a7 100644
--- a/src/synchronizer/distributed_synchronizer.cc
+++ b/src/synchronizer/distributed_synchronizer.cc
@@ -1,1722 +1,1725 @@
/**
* @file distributed_synchronizer.cc
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Wed Sep 01 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief implementation of a communicator using a static_communicator for real
* send/receive
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "distributed_synchronizer.hh"
#include "static_communicator.hh"
#include "mesh_utils.hh"
#include "mesh_data.hh"
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
#include <map>
#include <iostream>
#include <algorithm>
#if defined(AKANTU_DEBUG_TOOLS)
# include "aka_debug_tools.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
DistributedSynchronizer::DistributedSynchronizer(Mesh & mesh,
SynchronizerID id,
MemoryID memory_id,
const bool register_to_event_manager) :
Synchronizer(id, memory_id),
mesh(mesh),
prank_to_element("prank_to_element", id)
{
AKANTU_DEBUG_IN();
nb_proc = static_communicator->getNbProc();
rank = static_communicator->whoAmI();
send_element = new Array<Element>[nb_proc];
recv_element = new Array<Element>[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
std::stringstream sstr; sstr << p;
send_element[p].setID(id+":send_elements_"+sstr.str());
recv_element[p].setID(id+":recv_elements_"+sstr.str());
}
if (register_to_event_manager)
mesh.registerEventHandler(*this);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
DistributedSynchronizer::~DistributedSynchronizer() {
AKANTU_DEBUG_IN();
for (UInt p = 0; p < nb_proc; ++p) {
send_element[p].clear();
recv_element[p].clear();
}
delete [] send_element;
delete [] recv_element;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
DistributedSynchronizer * DistributedSynchronizer::
createDistributedSynchronizerMesh(Mesh & mesh,
const MeshPartition * partition,
UInt root,
SynchronizerID id,
MemoryID memory_id) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
DistributedSynchronizer & communicator = *(new DistributedSynchronizer(mesh, id, memory_id));
if(nb_proc == 1) return &communicator;
UInt * local_connectivity = NULL;
UInt * local_partitions = NULL;
Array<UInt> * old_nodes = mesh.getNodesGlobalIdsPointer();
old_nodes->resize(0);
Array<Real> * nodes = mesh.getNodesPointer();
UInt spatial_dimension = nodes->getNbComponent();
mesh.synchronizeGroupNames();
/* ------------------------------------------------------------------------ */
/* Local (rank == root) */
/* ------------------------------------------------------------------------ */
if(my_rank == root) {
AKANTU_DEBUG_ASSERT(partition->getNbPartition() == nb_proc,
"The number of partition does not match the number of processors: " <<
partition->getNbPartition() << " != " << nb_proc);
/**
* connectivity and communications scheme construction
*/
Mesh::type_iterator it = mesh.firstType(_all_dimensions,
_not_ghost,
_ek_not_defined);
Mesh::type_iterator end = mesh.lastType(_all_dimensions,
_not_ghost,
_ek_not_defined);
UInt count = 0;
/* --- MAIN LOOP ON TYPES --- */
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_element = mesh.getNbElement(*it);
UInt nb_local_element[nb_proc];
UInt nb_ghost_element[nb_proc];
UInt nb_element_to_send[nb_proc];
memset(nb_local_element, 0, nb_proc*sizeof(UInt));
memset(nb_ghost_element, 0, nb_proc*sizeof(UInt));
memset(nb_element_to_send, 0, nb_proc*sizeof(UInt));
/// \todo change this ugly way to avoid a problem if an element
/// type is present in the mesh but not in the partitions
const Array<UInt> * tmp_partition_num = NULL;
try {
tmp_partition_num = &partition->getPartition(type, _not_ghost);
} catch(...) {
continue;
}
const Array<UInt> & partition_num = *tmp_partition_num;
const CSR<UInt> & ghost_partition = partition->getGhostPartitionCSR()(type, _not_ghost);
/* -------------------------------------------------------------------- */
/// constructing the reordering structures
for (UInt el = 0; el < nb_element; ++el) {
nb_local_element[partition_num(el)]++;
for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
part != ghost_partition.end(el);
++part) {
nb_ghost_element[*part]++;
}
nb_element_to_send[partition_num(el)] += ghost_partition.getNbCols(el) + 1;
}
/// allocating buffers
UInt * buffers[nb_proc];
UInt * buffers_tmp[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
UInt size = nb_nodes_per_element * (nb_local_element[p] +
nb_ghost_element[p]);
buffers[p] = new UInt[size];
buffers_tmp[p] = buffers[p];
}
/// copying the local connectivity
UInt * conn_val = mesh.getConnectivity(type, _not_ghost).storage();
for (UInt el = 0; el < nb_element; ++el) {
memcpy(buffers_tmp[partition_num(el)],
conn_val + el * nb_nodes_per_element,
nb_nodes_per_element * sizeof(UInt));
buffers_tmp[partition_num(el)] += nb_nodes_per_element;
}
/// copying the connectivity of ghost element
for (UInt el = 0; el < nb_element; ++el) {
for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
part != ghost_partition.end(el);
++part) {
UInt proc = *part;
memcpy(buffers_tmp[proc],
conn_val + el * nb_nodes_per_element,
nb_nodes_per_element * sizeof(UInt));
buffers_tmp[proc] += nb_nodes_per_element;
}
}
/// tag info
std::vector<std::string> tag_names;
mesh.getMeshData().getTagNames(tag_names, type);
UInt nb_tags = tag_names.size();
/* -------->>>>-SIZE + CONNECTIVITY------------------------------------ */
/// send all connectivity and ghost information to all processors
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
UInt size[5];
size[0] = (UInt) type;
size[1] = nb_local_element[p];
size[2] = nb_ghost_element[p];
size[3] = nb_element_to_send[p];
size[4] = nb_tags;
AKANTU_DEBUG_INFO("Sending connectivities informations to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_SIZES) <<")");
comm.send(size, 5, p, Tag::genTag(my_rank, count, TAG_SIZES));
AKANTU_DEBUG_INFO("Sending connectivities to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_CONNECTIVITY) <<")");
requests.push_back(comm.asyncSend(buffers[p],
nb_nodes_per_element * (nb_local_element[p] +
nb_ghost_element[p]),
p, Tag::genTag(my_rank, count, TAG_CONNECTIVITY)));
} else {
local_connectivity = buffers[p];
}
}
/// create the renumbered connectivity
AKANTU_DEBUG_INFO("Renumbering local connectivities");
MeshUtils::renumberMeshNodes(mesh,
local_connectivity,
nb_local_element[root],
nb_ghost_element[root],
type,
*old_nodes);
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
for (UInt p = 0; p < nb_proc; ++p) {
delete [] buffers[p];
}
/* -------------------------------------------------------------------- */
for (UInt p = 0; p < nb_proc; ++p) {
buffers[p] = new UInt[nb_ghost_element[p] + nb_element_to_send[p]];
buffers_tmp[p] = buffers[p];
}
/// splitting the partition information to send them to processors
UInt count_by_proc[nb_proc];
memset(count_by_proc, 0, nb_proc*sizeof(UInt));
for (UInt el = 0; el < nb_element; ++el) {
*(buffers_tmp[partition_num(el)]++) = ghost_partition.getNbCols(el);
UInt i(0);
for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
part != ghost_partition.end(el);
++part, ++i) {
*(buffers_tmp[partition_num(el)]++) = *part;
}
}
for (UInt el = 0; el < nb_element; ++el) {
UInt i(0);
for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
part != ghost_partition.end(el);
++part, ++i) {
*(buffers_tmp[*part]++) = partition_num(el);
}
}
/* -------->>>>-PARTITIONS--------------------------------------------- */
/// last data to compute the communication scheme
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
AKANTU_DEBUG_INFO("Sending partition informations to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_PARTITIONS) <<")");
requests.push_back(comm.asyncSend(buffers[p],
nb_element_to_send[p] + nb_ghost_element[p],
p, Tag::genTag(my_rank, count, TAG_PARTITIONS)));
} else {
local_partitions = buffers[p];
}
}
if(Mesh::getSpatialDimension(type) == mesh.getSpatialDimension()) {
AKANTU_DEBUG_INFO("Creating communications scheme");
communicator.fillCommunicationScheme(local_partitions,
nb_local_element[root],
nb_ghost_element[root],
type);
}
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
for (UInt p = 0; p < nb_proc; ++p) {
delete [] buffers[p];
}
/* -------------------------------------------------------------------- */
/// send data assossiated to the mesh
/* -------->>>>-TAGS--------------------------------------------------- */
synchronizeTagsSend(communicator, root, mesh, nb_tags, type,
partition_num,
ghost_partition,
nb_local_element[root],
nb_ghost_element[root]);
/* -------------------------------------------------------------------- */
/// send data assossiated to groups
/* -------->>>>-GROUPS------------------------------------------------- */
synchronizeElementGroups(communicator, root, mesh, type,
partition_num,
ghost_partition,
nb_element);
++count;
}
/* -------->>>>-SIZE----------------------------------------------------- */
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
UInt size[5];
size[0] = (UInt) _not_defined;
size[1] = 0;
size[2] = 0;
size[3] = 0;
size[4] = 0;
AKANTU_DEBUG_INFO("Sending empty connectivities informations to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_SIZES) <<")");
comm.send(size, 5, p, Tag::genTag(my_rank, count, TAG_SIZES));
}
}
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/**
* Nodes coordinate construction and synchronization
*/
std::multimap< UInt, std::pair<UInt, UInt> > nodes_to_proc;
/// get the list of nodes to send and send them
Real * local_nodes = NULL;
UInt nb_nodes_per_proc[nb_proc];
UInt * nodes_per_proc[nb_proc];
comm.broadcast(&(mesh.nb_global_nodes), 1, root);
/* --------<<<<-NB_NODES + NODES----------------------------------------- */
for (UInt p = 0; p < nb_proc; ++p) {
UInt nb_nodes = 0;
// UInt * buffer;
if(p != root) {
AKANTU_DEBUG_INFO("Receiving number of nodes from proc " << p << " TAG("<< Tag::genTag(p, 0, TAG_NB_NODES) <<")");
comm.receive(&nb_nodes, 1, p, Tag::genTag(p, 0, TAG_NB_NODES));
nodes_per_proc[p] = new UInt[nb_nodes];
nb_nodes_per_proc[p] = nb_nodes;
AKANTU_DEBUG_INFO("Receiving list of nodes from proc " << p << " TAG("<< Tag::genTag(p, 0, TAG_NODES) <<")");
comm.receive(nodes_per_proc[p], nb_nodes, p, Tag::genTag(p, 0, TAG_NODES));
} else {
nb_nodes = old_nodes->getSize();
nb_nodes_per_proc[p] = nb_nodes;
nodes_per_proc[p] = old_nodes->storage();
}
/// get the coordinates for the selected nodes
Real * nodes_to_send = new Real[nb_nodes * spatial_dimension];
Real * nodes_to_send_tmp = nodes_to_send;
for (UInt n = 0; n < nb_nodes; ++n) {
memcpy(nodes_to_send_tmp,
nodes->storage() + spatial_dimension * nodes_per_proc[p][n],
spatial_dimension * sizeof(Real));
// nodes_to_proc.insert(std::make_pair(buffer[n], std::make_pair(p, n)));
nodes_to_send_tmp += spatial_dimension;
}
/* -------->>>>-COORDINATES-------------------------------------------- */
if(p != root) { /// send them for distant processors
AKANTU_DEBUG_INFO("Sending coordinates to proc " << p << " TAG("<< Tag::genTag(my_rank, 0, TAG_COORDINATES) <<")");
comm.send(nodes_to_send, nb_nodes * spatial_dimension, p, Tag::genTag(my_rank, 0, TAG_COORDINATES));
delete [] nodes_to_send;
} else { /// save them for local processor
local_nodes = nodes_to_send;
}
}
/// construct the local nodes coordinates
UInt nb_nodes = old_nodes->getSize();
nodes->resize(nb_nodes);
memcpy(nodes->storage(), local_nodes, nb_nodes * spatial_dimension * sizeof(Real));
delete [] local_nodes;
Array<Int> * nodes_type_per_proc[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
nodes_type_per_proc[p] = new Array<Int>(nb_nodes_per_proc[p]);
}
communicator.fillNodesType(mesh);
/* --------<<<<-NODES_TYPE-1--------------------------------------------- */
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
AKANTU_DEBUG_INFO("Receiving first nodes types from proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_NODES_TYPE) <<")");
comm.receive(nodes_type_per_proc[p]->storage(),
nb_nodes_per_proc[p], p, Tag::genTag(p, 0, TAG_NODES_TYPE));
} else {
nodes_type_per_proc[p]->copy(mesh.getNodesType());
}
for (UInt n = 0; n < nb_nodes_per_proc[p]; ++n) {
if((*nodes_type_per_proc[p])(n) == -2)
nodes_to_proc.insert(std::make_pair(nodes_per_proc[p][n], std::make_pair(p, n)));
}
}
std::multimap< UInt, std::pair<UInt, UInt> >::iterator it_node;
std::pair< std::multimap< UInt, std::pair<UInt, UInt> >::iterator,
std::multimap< UInt, std::pair<UInt, UInt> >::iterator > it_range;
for (UInt i = 0; i < mesh.nb_global_nodes; ++i) {
it_range = nodes_to_proc.equal_range(i);
if(it_range.first == nodes_to_proc.end() || it_range.first->first != i) continue;
UInt node_type = (it_range.first)->second.first;
for (it_node = it_range.first; it_node != it_range.second; ++it_node) {
UInt proc = it_node->second.first;
UInt node = it_node->second.second;
if(proc != node_type)
nodes_type_per_proc[proc]->storage()[node] = node_type;
}
}
/* -------->>>>-NODES_TYPE-2--------------------------------------------- */
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
AKANTU_DEBUG_INFO("Sending nodes types to proc " << p << " TAG("<< Tag::genTag(my_rank, 0, TAG_NODES_TYPE) <<")");
requests.push_back(comm.asyncSend(nodes_type_per_proc[p]->storage(),
nb_nodes_per_proc[p], p, Tag::genTag(my_rank, 0, TAG_NODES_TYPE)));
} else {
mesh.getNodesTypePointer()->copy(*nodes_type_per_proc[p]);
}
}
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) delete [] nodes_per_proc[p];
delete nodes_type_per_proc[p];
}
/* -------->>>>-NODE GROUPS --------------------------------------------- */
synchronizeNodeGroupsMaster(communicator, root, mesh);
/* ---------------------------------------------------------------------- */
/* Distant (rank != root) */
/* ---------------------------------------------------------------------- */
} else {
/**
* connectivity and communications scheme construction on distant processors
*/
ElementType type = _not_defined;
UInt count = 0;
do {
/* --------<<<<-SIZE--------------------------------------------------- */
UInt size[5] = { 0 };
comm.receive(size, 5, root, Tag::genTag(root, count, TAG_SIZES));
type = (ElementType) size[0];
UInt nb_local_element = size[1];
UInt nb_ghost_element = size[2];
UInt nb_element_to_send = size[3];
UInt nb_tags = size[4];
if(type != _not_defined) {
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
/* --------<<<<-CONNECTIVITY----------------------------------------- */
local_connectivity = new UInt[(nb_local_element + nb_ghost_element) *
nb_nodes_per_element];
AKANTU_DEBUG_INFO("Receiving connectivities from proc " << root);
comm.receive(local_connectivity, nb_nodes_per_element * (nb_local_element +
nb_ghost_element),
root, Tag::genTag(root, count, TAG_CONNECTIVITY));
AKANTU_DEBUG_INFO("Renumbering local connectivities");
MeshUtils::renumberMeshNodes(mesh,
local_connectivity,
nb_local_element,
nb_ghost_element,
type,
*old_nodes);
delete [] local_connectivity;
/* --------<<<<-PARTITIONS--------------------------------------------- */
local_partitions = new UInt[nb_element_to_send + nb_ghost_element * 2];
AKANTU_DEBUG_INFO("Receiving partition informations from proc " << root);
comm.receive(local_partitions,
nb_element_to_send + nb_ghost_element * 2,
root, Tag::genTag(root, count, TAG_PARTITIONS));
if(Mesh::getSpatialDimension(type) == mesh.getSpatialDimension()) {
AKANTU_DEBUG_INFO("Creating communications scheme");
communicator.fillCommunicationScheme(local_partitions,
nb_local_element,
nb_ghost_element,
type);
}
delete [] local_partitions;
/* --------<<<<-TAGS------------------------------------------------- */
synchronizeTagsRecv(communicator, root, mesh, nb_tags, type,
nb_local_element,
nb_ghost_element);
/* --------<<<<-GROUPS----------------------------------------------- */
synchronizeElementGroups(communicator, root, mesh, type);
}
++count;
} while(type != _not_defined);
/**
* Nodes coordinate construction and synchronization on distant processors
*/
comm.broadcast(&(mesh.nb_global_nodes), 1, root);
/* -------->>>>-NB_NODES + NODES----------------------------------------- */
AKANTU_DEBUG_INFO("Sending list of nodes to proc " << root);
UInt nb_nodes = old_nodes->getSize();
comm.send(&nb_nodes, 1, root, Tag::genTag(my_rank, 0, TAG_NB_NODES));
comm.send(old_nodes->storage(), nb_nodes, root, Tag::genTag(my_rank, 0, TAG_NODES));
/* --------<<<<-COORDINATES---------------------------------------------- */
nodes->resize(nb_nodes);
AKANTU_DEBUG_INFO("Receiving coordinates from proc " << root);
comm.receive(nodes->storage(), nb_nodes * spatial_dimension, root, Tag::genTag(root, 0, TAG_COORDINATES));
communicator.fillNodesType(mesh);
/* -------->>>>-NODES_TYPE-1--------------------------------------------- */
Int * nodes_types = mesh.getNodesTypePointer()->storage();
AKANTU_DEBUG_INFO("Sending first nodes types to proc " << root);
comm.send(nodes_types, nb_nodes,
root, Tag::genTag(my_rank, 0, TAG_NODES_TYPE));
/* --------<<<<-NODES_TYPE-2--------------------------------------------- */
AKANTU_DEBUG_INFO("Receiving nodes types from proc " << root);
comm.receive(nodes_types, nb_nodes,
root, Tag::genTag(root, 0, TAG_NODES_TYPE));
/* --------<<<<-NODE GROUPS --------------------------------------------- */
synchronizeNodeGroupsSlaves(communicator, root, mesh);
}
MeshUtils::fillElementToSubElementsData(mesh);
mesh.is_distributed = true;
AKANTU_DEBUG_OUT();
return &communicator;
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::fillTagBuffer(const MeshData & mesh_data,
DynamicCommunicationBuffer * buffers,
const std::string & tag_name,
const ElementType & el_type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition) {
#define AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA(r, extra_param, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem) : { \
fillTagBufferTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(mesh_data, buffers, tag_name, el_type, partition_num, ghost_partition); \
break; \
} \
MeshDataTypeCode data_type_code = mesh_data.getTypeCode(tag_name);
switch(data_type_code) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA, , AKANTU_MESH_DATA_TYPES)
default : AKANTU_DEBUG_ERROR("Could not obtain the type of tag" << tag_name << "!"); break;
}
#undef AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::fillNodesType(Mesh & mesh) {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
Int * nodes_type = mesh.getNodesTypePointer()->storage();
UInt * nodes_set = new UInt[nb_nodes];
std::fill_n(nodes_set, nb_nodes, 0);
const UInt NORMAL_SET = 1;
const UInt GHOST_SET = 2;
bool * already_seen = new bool[nb_nodes];
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
UInt set = NORMAL_SET;
if (gt == _ghost) set = GHOST_SET;
std::fill_n(already_seen, nb_nodes, false);
Mesh::type_iterator it = mesh.firstType(_all_dimensions, gt, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType(_all_dimensions, gt, _ek_not_defined);
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_element = mesh.getNbElement(type, gt);
Array<UInt>::iterator< Vector<UInt> > conn_it = mesh.getConnectivity(type, gt).begin(nb_nodes_per_element);
for (UInt e = 0; e < nb_element; ++e, ++conn_it) {
Vector<UInt> & conn = *conn_it;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
AKANTU_DEBUG_ASSERT(conn(n) < nb_nodes, "Node " << conn(n)
<< " bigger than number of nodes " << nb_nodes);
if(!already_seen[conn(n)]) {
nodes_set[conn(n)] += set;
already_seen[conn(n)] = true;
}
}
}
}
}
delete [] already_seen;
for (UInt i = 0; i < nb_nodes; ++i) {
if(nodes_set[i] == NORMAL_SET) nodes_type[i] = -1;
else if(nodes_set[i] == GHOST_SET) nodes_type[i] = -3;
else if(nodes_set[i] == (GHOST_SET + NORMAL_SET)) nodes_type[i] = -2;
}
delete [] nodes_set;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::fillCommunicationScheme(const UInt * partition,
UInt nb_local_element,
UInt nb_ghost_element,
ElementType type) {
AKANTU_DEBUG_IN();
Element element;
element.type = type;
element.kind = Mesh::getKind(type);
const UInt * part = partition;
part = partition;
for (UInt lel = 0; lel < nb_local_element; ++lel) {
UInt nb_send = *part; part++;
element.element = lel;
element.ghost_type = _not_ghost;
for (UInt p = 0; p < nb_send; ++p) {
UInt proc = *part; part++;
AKANTU_DEBUG(dblAccessory, "Must send : " << element << " to proc " << proc);
(send_element[proc]).push_back(element);
}
}
for (UInt gel = 0; gel < nb_ghost_element; ++gel) {
UInt proc = *part; part++;
element.element = gel;
element.ghost_type = _ghost;
AKANTU_DEBUG(dblAccessory, "Must recv : " << element << " from proc " << proc);
recv_element[proc].push_back(element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::asynchronousSynchronize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
if (communications.find(tag) == communications.end())
computeBufferSize(data_accessor, tag);
Communication & communication = communications[tag];
AKANTU_DEBUG_ASSERT(communication.send_requests.size() == 0,
"There must be some pending sending communications. Tag is " << tag);
std::map<SynchronizationTag, UInt>::iterator t_it = tag_counter.find(tag);
UInt counter = 0;
if(t_it == tag_counter.end()) {
tag_counter[tag] = 0;
} else {
counter = ++(t_it->second);
}
for (UInt p = 0; p < nb_proc; ++p) {
UInt ssize = communication.size_to_send[p];
if(p == rank || ssize == 0) continue;
CommunicationBuffer & buffer = communication.send_buffer[p];
buffer.resize(ssize);
Tag comm_tag = Tag::genTag(rank, counter, tag);
buffer << int(comm_tag);
#ifndef AKANTU_NDEBUG
UInt nb_elements = send_element[p].getSize();
AKANTU_DEBUG_INFO("Packing data for proc " << p
<< " (" << ssize << "/" << nb_elements
<<" data to send/elements)");
/// pack barycenters in debug mode
Array<Element>::const_iterator<Element> bit = send_element[p].begin();
Array<Element>::const_iterator<Element> bend = send_element[p].end();
for (; bit != bend; ++bit) {
const Element & element = *bit;
Vector<Real> barycenter(mesh.getSpatialDimension());
mesh.getBarycenter(element.element, element.type, barycenter.storage(), element.ghost_type);
buffer << barycenter;
}
#endif
data_accessor.packElementData(buffer, send_element[p], tag);
AKANTU_DEBUG_ASSERT(buffer.getPackedSize() == ssize,
"a problem have been introduced with "
<< "false sent sizes declaration "
<< buffer.getPackedSize() << " != " << ssize);
AKANTU_DEBUG_INFO("Posting send to proc " << p
<< " (tag: " << tag << " - " << ssize << " data to send)"
<< " [ " << comm_tag << ":" << std::hex << int(this->genTagFromID(tag)) << " ]");
communication.send_requests.push_back(static_communicator->asyncSend(buffer.storage(),
ssize,
p,
this->genTagFromID(tag)));
}
AKANTU_DEBUG_ASSERT(communication.recv_requests.size() == 0,
"There must be some pending receive communications");
for (UInt p = 0; p < nb_proc; ++p) {
UInt rsize = communication.size_to_receive[p];
if(p == rank || rsize == 0) continue;
CommunicationBuffer & buffer = communication.recv_buffer[p];
buffer.resize(rsize);
Tag comm_tag = Tag::genTag(rank, counter, tag);
buffer << int(comm_tag);
AKANTU_DEBUG_INFO("Posting receive from proc " << p
<< " (tag: " << tag << " - " << rsize << " data to receive) "
<< " [ " << comm_tag << ":" << std::hex << int(this->genTagFromID(tag)) << " ]");
communication.recv_requests.push_back(static_communicator->asyncReceive(buffer.storage(),
rsize,
p,
this->genTagFromID(tag)));
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::waitEndSynchronize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(communications.find(tag) != communications.end(), "No communication with the tag \""
<< tag <<"\" started");
Communication & communication = communications[tag];
std::vector<CommunicationRequest *> req_not_finished;
std::vector<CommunicationRequest *> * req_not_finished_tmp = &req_not_finished;
std::vector<CommunicationRequest *> * recv_requests_tmp = &(communication.recv_requests);
// static_communicator->waitAll(recv_requests);
while(!recv_requests_tmp->empty()) {
for (std::vector<CommunicationRequest *>::iterator req_it = recv_requests_tmp->begin();
req_it != recv_requests_tmp->end() ; ++req_it) {
CommunicationRequest * req = *req_it;
if(static_communicator->testRequest(req)) {
UInt proc = req->getSource();
AKANTU_DEBUG_INFO("Unpacking data coming from proc " << proc);
CommunicationBuffer & buffer = communication.recv_buffer[proc];
int _tag; buffer >> _tag;
Tag comm_tag(_tag);
#ifndef AKANTU_NDEBUG
Array<Element>::const_iterator<Element> bit = recv_element[proc].begin();
Array<Element>::const_iterator<Element> bend = recv_element[proc].end();
UInt spatial_dimension = mesh.getSpatialDimension();
for (; bit != bend; ++bit) {
const Element & element = *bit;
Vector<Real> barycenter_loc(spatial_dimension);
mesh.getBarycenter(element.element,
element.type,
barycenter_loc.storage(),
element.ghost_type);
Vector<Real> barycenter(spatial_dimension);
buffer >> barycenter;
Real tolerance = Math::getTolerance();
Real bary_norm = barycenter.norm();
for (UInt i = 0; i < spatial_dimension; ++i) {
if((std::abs(barycenter_loc(i)) <= tolerance && std::abs(barycenter(i)) <= tolerance) ||
(std::abs((barycenter(i) - barycenter_loc(i))/bary_norm) <= tolerance)) continue;
AKANTU_DEBUG_ERROR("Unpacking an unknown value for the element: "
<< element
<< "(barycenter[" << i << "] = " << barycenter_loc(i)
<< " and buffer[" << i << "] = " << barycenter(i) << ") ["
<< std::abs((barycenter(i) - barycenter_loc(i))/bary_norm)
<< "] - tag: " << tag
<< " comm_tag[ " << comm_tag << " ]");
}
}
#endif
data_accessor.unpackElementData(buffer, recv_element[proc], tag);
buffer.resize(0);
AKANTU_DEBUG_ASSERT(buffer.getLeftToUnpack() == 0,
"all data have not been unpacked: "
<< buffer.getLeftToUnpack() << " bytes left"
<< " [ " << comm_tag << " ]");
static_communicator->freeCommunicationRequest(req);
} else {
req_not_finished_tmp->push_back(req);
}
}
std::vector<CommunicationRequest *> * swap = req_not_finished_tmp;
req_not_finished_tmp = recv_requests_tmp;
recv_requests_tmp = swap;
req_not_finished_tmp->clear();
}
AKANTU_DEBUG_INFO("Waiting that every send requests are received");
static_communicator->waitAll(communication.send_requests);
for (std::vector<CommunicationRequest *>::iterator req_it = communication.send_requests.begin();
req_it != communication.send_requests.end() ; ++req_it) {
CommunicationRequest & req = *(*req_it);
if(static_communicator->testRequest(&req)) {
UInt proc = req.getDestination();
CommunicationBuffer & buffer = communication.send_buffer[proc];
buffer.resize(0);
static_communicator->freeCommunicationRequest(&req);
}
}
communication.send_requests.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::computeBufferSize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
communications[tag].resize(nb_proc);
for (UInt p = 0; p < nb_proc; ++p) {
UInt ssend = 0;
UInt sreceive = 0;
if(p != rank) {
if(send_element[p].getSize() != 0) {
ssend += sizeof(int); // sizeof(int) is for the communication tag
#ifndef AKANTU_NDEBUG
ssend += send_element[p].getSize() * mesh.getSpatialDimension() * sizeof(Real);
#endif
ssend += data_accessor.getNbDataForElements(send_element[p], tag);
AKANTU_DEBUG_INFO("I have " << ssend << "(" << ssend / 1024.
<< "kB - "<< send_element[p].getSize() <<" element(s)) data to send to " << p << " for tag "
<< tag);
}
if(recv_element[p].getSize() != 0) {
sreceive += sizeof(int); // sizeof(int) is for the communication tag
#ifndef AKANTU_NDEBUG
sreceive += recv_element[p].getSize() * mesh.getSpatialDimension() * sizeof(Real);
#endif
sreceive += data_accessor.getNbDataForElements(recv_element[p], tag);
AKANTU_DEBUG_INFO("I have " << sreceive << "(" << sreceive / 1024.
<< "kB - "<< recv_element[p].getSize() <<" element(s)) data to receive for tag "
<< tag);
}
}
communications[tag].size_to_send [p] = ssend;
communications[tag].size_to_receive[p] = sreceive;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::computeAllBufferSizes(DataAccessor & data_accessor) {
std::map<SynchronizationTag, Communication>::iterator it = this->communications.begin();
std::map<SynchronizationTag, Communication>::iterator end = this->communications.end();
for (; it != end; ++it) {
SynchronizationTag tag = it->first;
this->computeBufferSize(data_accessor, tag);
}
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
Int prank = StaticCommunicator::getStaticCommunicator().whoAmI();
Int psize = StaticCommunicator::getStaticCommunicator().getNbProc();
stream << "[" << prank << "/" << psize << "]" << space << "DistributedSynchronizer [" << std::endl;
for (UInt p = 0; p < nb_proc; ++p) {
if (p == UInt(prank)) continue;
stream << "[" << prank << "/" << psize << "]" << space
<< " + Communication to proc " << p << " [" << std::endl;
if(AKANTU_DEBUG_TEST(dblDump)) {
stream << "[" << prank << "/" << psize << "]" << space
<< " - Element to send to proc " << p << " [" << std::endl;
Array<Element>::iterator<Element> it_el = send_element[p].begin();
Array<Element>::iterator<Element> end_el = send_element[p].end();
for(;it_el != end_el; ++it_el)
stream << "[" << prank << "/" << psize << "]" << space << " " << *it_el << std::endl;
stream << "[" << prank << "/" << psize << "]" << space << " ]" << std::endl;
stream << "[" << prank << "/" << psize << "]" << space
<< " - Element to recv from proc " << p << " [" << std::endl;
it_el = recv_element[p].begin();
end_el = recv_element[p].end();
for(;it_el != end_el; ++it_el)
stream << "[" << prank << "/" << psize << "]"
<< space << " " << *it_el << std::endl;
stream << "[" << prank << "/" << psize << "]" << space << " ]" << std::endl;
}
std::map< SynchronizationTag, Communication>::const_iterator it = communications.begin();
std::map< SynchronizationTag, Communication>::const_iterator end = communications.end();
for (; it != end; ++it) {
const SynchronizationTag & tag = it->first;
const Communication & communication = it->second;
UInt ssend = communication.size_to_send[p];
UInt sreceive = communication.size_to_receive[p];
stream << "[" << prank << "/" << psize << "]" << space << " - Tag " << tag << " -> " << ssend << "byte(s) -- <- " << sreceive << "byte(s)" << std::endl;
}
}
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::substituteElements(const std::map<Element, Element> & old_to_new_elements) {
// substitute old elements with new ones
std::map<Element, Element>::const_iterator found_element_it;
std::map<Element, Element>::const_iterator found_element_end = old_to_new_elements.end();
for (UInt p = 0; p < nb_proc; ++p) {
if (p == rank) continue;
Array<Element> & recv = recv_element[p];
for (UInt el = 0; el < recv.getSize(); ++el) {
found_element_it = old_to_new_elements.find(recv(el));
if (found_element_it != found_element_end)
recv(el) = found_element_it->second;
}
Array<Element> & send = send_element[p];
for (UInt el = 0; el < send.getSize(); ++el) {
found_element_it = old_to_new_elements.find(send(el));
if (found_element_it != found_element_end)
send(el) = found_element_it->second;
}
}
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::onElementsChanged(const Array<Element> & old_elements_list,
const Array<Element> & new_elements_list,
__attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const ChangedElementsEvent & event) {
// create a map to link old elements to new ones
std::map<Element, Element> old_to_new_elements;
for (UInt el = 0; el < old_elements_list.getSize(); ++el) {
AKANTU_DEBUG_ASSERT(old_to_new_elements.find(old_elements_list(el)) == old_to_new_elements.end(),
"The same element cannot appear twice in the list");
old_to_new_elements[old_elements_list(el)] = new_elements_list(el);
}
substituteElements(old_to_new_elements);
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::onElementsRemoved(const Array<Element> & element_to_remove,
const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const RemovedElementsEvent & event) {
AKANTU_DEBUG_IN();
this->removeElements(element_to_remove);
this->renumberElements(new_numbering);
AKANTU_DEBUG_OUT();
}
// void DistributedSynchronizer::checkCommunicationScheme() {
// for (UInt p = 0; p < psize; ++p) {
// if (p == prank) continue;
// for(UInt e(0), e < recv_element.getSize())
// }
// }
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::buildPrankToElement() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
mesh.initElementTypeMapArray(prank_to_element,
1,
spatial_dimension,
false,
_ek_not_defined,
true);
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
_not_ghost,
_ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension,
_not_ghost,
_ek_not_defined);
/// assign prank to all not ghost elements
for (; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it);
Array<UInt> & prank_to_el = prank_to_element(*it);
for (UInt el = 0; el < nb_element; ++el) {
prank_to_el(el) = rank;
}
}
/// assign prank to all ghost elements
for (UInt p = 0; p < nb_proc; ++p) {
UInt nb_ghost_element = recv_element[p].getSize();
for (UInt el = 0; el < nb_ghost_element; ++el) {
UInt element = recv_element[p](el).element;
ElementType type = recv_element[p](el).type;
GhostType ghost_type = recv_element[p](el).ghost_type;
Array<UInt> & prank_to_el = prank_to_element(type, ghost_type);
prank_to_el(element) = p;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::filterElementsByKind(DistributedSynchronizer * new_synchronizer,
ElementKind kind) {
AKANTU_DEBUG_IN();
Array<Element> * newsy_send_element = new_synchronizer->send_element;
Array<Element> * newsy_recv_element = new_synchronizer->recv_element;
Array<Element> * new_send_element = new Array<Element>[nb_proc];
Array<Element> * new_recv_element = new Array<Element>[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
/// send element copying part
new_send_element[p].resize(0);
for (UInt el = 0; el < send_element[p].getSize(); ++el) {
Element & element = send_element[p](el);
if (element.kind == kind)
newsy_send_element[p].push_back(element);
else
new_send_element[p].push_back(element);
}
/// recv element copying part
new_recv_element[p].resize(0);
for (UInt el = 0; el < recv_element[p].getSize(); ++el) {
Element & element = recv_element[p](el);
if (element.kind == kind)
newsy_recv_element[p].push_back(element);
else
new_recv_element[p].push_back(element);
}
}
/// deleting and reassigning old pointers
delete [] send_element;
delete [] recv_element;
send_element = new_send_element;
recv_element = new_recv_element;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::reset() {
AKANTU_DEBUG_IN();
for (UInt p = 0; p < nb_proc; ++p) {
send_element[p].resize(0);
recv_element[p].resize(0);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeTagsSend(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
UInt nb_tags,
const ElementType & type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition,
UInt nb_local_element,
UInt nb_ghost_element) {
AKANTU_DEBUG_IN();
static UInt count = 0;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
if(nb_tags == 0) {
AKANTU_DEBUG_OUT();
return;
}
UInt mesh_data_sizes_buffer_length;
MeshData & mesh_data = mesh.getMeshData();
/// tag info
std::vector<std::string> tag_names;
mesh.getMeshData().getTagNames(tag_names, type);
// Make sure the tags are sorted (or at least not in random order),
// because they come from a map !!
std::sort(tag_names.begin(), tag_names.end());
// Sending information about the tags in mesh_data: name, data type and
// number of components of the underlying array associated to the current type
DynamicCommunicationBuffer mesh_data_sizes_buffer;
std::vector<std::string>::const_iterator names_it = tag_names.begin();
std::vector<std::string>::const_iterator names_end = tag_names.end();
for(;names_it != names_end; ++names_it) {
mesh_data_sizes_buffer << *names_it;
mesh_data_sizes_buffer << mesh_data.getTypeCode(*names_it);
mesh_data_sizes_buffer << mesh_data.getNbComponent(*names_it, type);
}
mesh_data_sizes_buffer_length = mesh_data_sizes_buffer.getSize();
AKANTU_DEBUG_INFO("Broadcasting the size of the information about the mesh data tags: (" << mesh_data_sizes_buffer_length << ")." );
comm.broadcast(&mesh_data_sizes_buffer_length, 1, root);
AKANTU_DEBUG_INFO("Broadcasting the information about the mesh data tags, addr " << (void*)mesh_data_sizes_buffer.storage());
if(mesh_data_sizes_buffer_length !=0)
comm.broadcast(mesh_data_sizes_buffer.storage(), mesh_data_sizes_buffer.getSize(), root);
if(mesh_data_sizes_buffer_length !=0) {
//Sending the actual data to each processor
DynamicCommunicationBuffer * buffers = new DynamicCommunicationBuffer[nb_proc];
std::vector<std::string>::const_iterator names_it = tag_names.begin();
std::vector<std::string>::const_iterator names_end = tag_names.end();
// Loop over each tag for the current type
for(;names_it != names_end; ++names_it) {
// Type code of the current tag (i.e. the tag named *names_it)
communicator.fillTagBuffer(mesh_data,
buffers,
*names_it,
type,
partition_num,
ghost_partition);
}
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
AKANTU_DEBUG_INFO("Sending " << buffers[p].getSize() << " bytes of mesh data to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_MESH_DATA) <<")");
requests.push_back(comm.asyncSend(buffers[p].storage(),
buffers[p].getSize(), p, Tag::genTag(my_rank, count, TAG_MESH_DATA)));
}
}
names_it = tag_names.begin();
// Loop over each tag for the current type
for(;names_it != names_end; ++names_it) {
// Reinitializing the mesh data on the master
communicator.populateMeshData(mesh_data,
buffers[root],
*names_it,
type,
mesh_data.getTypeCode(*names_it),
mesh_data.getNbComponent(*names_it, type),
nb_local_element,
nb_ghost_element);
}
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
delete [] buffers;
}
++count;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeTagsRecv(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
UInt nb_tags,
const ElementType & type,
UInt nb_local_element,
UInt nb_ghost_element) {
AKANTU_DEBUG_IN();
static UInt count = 0;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
if(nb_tags == 0) {
AKANTU_DEBUG_OUT();
return;
}
/* --------<<<<-TAGS------------------------------------------------- */
UInt mesh_data_sizes_buffer_length = 0;
CommunicationBuffer mesh_data_sizes_buffer;
MeshData & mesh_data = mesh.getMeshData();
AKANTU_DEBUG_INFO("Receiving the size of the information about the mesh data tags.");
comm.broadcast(&mesh_data_sizes_buffer_length, 1, root);
if(mesh_data_sizes_buffer_length != 0) {
mesh_data_sizes_buffer.resize(mesh_data_sizes_buffer_length);
AKANTU_DEBUG_INFO("Receiving the information about the mesh data tags, addr " << (void*)mesh_data_sizes_buffer.storage());
comm.broadcast(mesh_data_sizes_buffer.storage(), mesh_data_sizes_buffer_length, root);
AKANTU_DEBUG_INFO("Size of the information about the mesh data: " << mesh_data_sizes_buffer_length);
std::vector<std::string> tag_names;
std::vector<MeshDataTypeCode> tag_type_codes;
std::vector<UInt> tag_nb_component;
tag_names.resize(nb_tags);
tag_type_codes.resize(nb_tags);
tag_nb_component.resize(nb_tags);
CommunicationBuffer mesh_data_buffer;
UInt type_code_int;
for(UInt i(0); i < nb_tags; ++i) {
mesh_data_sizes_buffer >> tag_names[i];
mesh_data_sizes_buffer >> type_code_int;
tag_type_codes[i] = static_cast<MeshDataTypeCode>(type_code_int);
mesh_data_sizes_buffer >> tag_nb_component[i];
}
std::vector<std::string>::const_iterator names_it = tag_names.begin();
std::vector<std::string>::const_iterator names_end = tag_names.end();
CommunicationStatus mesh_data_comm_status;
AKANTU_DEBUG_INFO("Checking size of data to receive for mesh data TAG("
<< Tag::genTag(root, count, TAG_MESH_DATA) << ")");
comm.probe<char>(root, Tag::genTag(root, count, TAG_MESH_DATA), mesh_data_comm_status);
UInt mesh_data_buffer_size(mesh_data_comm_status.getSize());
AKANTU_DEBUG_INFO("Receiving " << mesh_data_buffer_size
<< " bytes of mesh data TAG("
<< Tag::genTag(root, count, TAG_MESH_DATA) << ")");
mesh_data_buffer.resize(mesh_data_buffer_size);
comm.receive(mesh_data_buffer.storage(),
mesh_data_buffer_size,
root,
Tag::genTag(root, count, TAG_MESH_DATA));
// Loop over each tag for the current type
UInt k(0);
for(; names_it != names_end; ++names_it, ++k) {
communicator.populateMeshData(mesh_data, mesh_data_buffer,
*names_it, type,
tag_type_codes[k],
tag_nb_component[k],
nb_local_element, nb_ghost_element);
}
}
++count;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class CommunicationBuffer>
void DistributedSynchronizer::fillElementGroupsFromBuffer(DistributedSynchronizer & communicator,
Mesh & mesh,
const ElementType & type,
CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
Element el;
el.type = type;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
UInt nb_element = mesh.getNbElement(type, *gt);
el.ghost_type = *gt;
for (UInt e = 0; e < nb_element; ++e) {
el.element = e;
std::vector<std::string> element_to_group;
buffer >> element_to_group;
AKANTU_DEBUG_ASSERT(e < mesh.getNbElement(type, *gt), "The mesh does not have the element " << e);
std::vector<std::string>::iterator it = element_to_group.begin();
std::vector<std::string>::iterator end = element_to_group.end();
for (; it != end; ++it) {
mesh.getElementGroup(*it).add(el, false, false);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeElementGroups(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
const ElementType & type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition,
UInt nb_element) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
DynamicCommunicationBuffer * buffers = new DynamicCommunicationBuffer[nb_proc];
typedef std::vector< std::vector<std::string> > ElementToGroup;
ElementToGroup element_to_group;
element_to_group.resize(nb_element);
GroupManager::const_element_group_iterator egi = mesh.element_group_begin();
GroupManager::const_element_group_iterator ege = mesh.element_group_end();
for (; egi != ege; ++egi) {
ElementGroup & eg = *(egi->second);
std::string name = egi->first;
ElementGroup::const_element_iterator eit = eg.element_begin(type, _not_ghost);
ElementGroup::const_element_iterator eend = eg.element_end(type, _not_ghost);
for (; eit != eend; ++eit) {
element_to_group[*eit].push_back(name);
}
eit = eg.element_begin(type, _not_ghost);
if(eit != eend)
const_cast<Array<UInt> &>(eg.getElements(type)).empty();
}
/// preparing the buffers
const UInt * part = partition_num.storage();
/// copying the data, element by element
ElementToGroup::const_iterator data_it = element_to_group.begin();
ElementToGroup::const_iterator data_end = element_to_group.end();
for (; data_it != data_end; ++part, ++data_it) {
buffers[*part] << *data_it;
}
data_it = element_to_group.begin();
/// copying the data for the ghost element
for (UInt el(0); data_it != data_end; ++data_it, ++el) {
CSR<UInt>::const_iterator it = ghost_partition.begin(el);
CSR<UInt>::const_iterator end = ghost_partition.end(el);
for (;it != end; ++it) {
UInt proc = *it;
buffers[proc] << *data_it;
}
}
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank) continue;
AKANTU_DEBUG_INFO("Sending element groups to proc " << p
<< " TAG("<< Tag::genTag(my_rank, p, TAG_ELEMENT_GROUP) <<")");
requests.push_back(comm.asyncSend(buffers[p].storage(),
buffers[p].getSize(),
p,
Tag::genTag(my_rank, p, TAG_ELEMENT_GROUP)));
}
fillElementGroupsFromBuffer(communicator, mesh, type, buffers[my_rank]);
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
delete [] buffers;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeElementGroups(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
const ElementType & type) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt my_rank = comm.whoAmI();
AKANTU_DEBUG_INFO("Receiving element groups from proc " << root
<< " TAG("<< Tag::genTag(root, my_rank, TAG_ELEMENT_GROUP) <<")");
CommunicationStatus status;
comm.probe<char>(root, Tag::genTag(root, my_rank, TAG_ELEMENT_GROUP), status);
CommunicationBuffer buffer(status.getSize());
comm.receive(buffer.storage(), buffer.getSize(), root, Tag::genTag(root, my_rank, TAG_ELEMENT_GROUP));
fillElementGroupsFromBuffer(communicator, mesh, type, buffer);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class CommunicationBuffer>
void DistributedSynchronizer::fillNodeGroupsFromBuffer(DistributedSynchronizer & communicator,
Mesh & mesh,
CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
std::vector< std::vector<std::string> > node_to_group;
buffer >> node_to_group;
AKANTU_DEBUG_ASSERT(node_to_group.size() == mesh.getNbGlobalNodes(),
"Not the good amount of nodes where transmitted");
const Array<UInt> & global_nodes = mesh.getGlobalNodesIds();
Array<UInt>::const_scalar_iterator nbegin = global_nodes.begin();
Array<UInt>::const_scalar_iterator nit = global_nodes.begin();
Array<UInt>::const_scalar_iterator nend = global_nodes.end();
for (; nit != nend; ++nit) {
std::vector<std::string>::iterator it = node_to_group[*nit].begin();
std::vector<std::string>::iterator end = node_to_group[*nit].end();
for (; it != end; ++it) {
mesh.getNodeGroup(*it).add(nit - nbegin, false);
}
}
GroupManager::const_node_group_iterator ngi = mesh.node_group_begin();
GroupManager::const_node_group_iterator nge = mesh.node_group_end();
for (; ngi != nge; ++ngi) {
NodeGroup & ng = *(ngi->second);
ng.optimize();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeNodeGroupsMaster(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
UInt nb_total_nodes = mesh.getNbGlobalNodes();
DynamicCommunicationBuffer buffer;
typedef std::vector< std::vector<std::string> > NodeToGroup;
NodeToGroup node_to_group;
node_to_group.resize(nb_total_nodes);
GroupManager::const_node_group_iterator ngi = mesh.node_group_begin();
GroupManager::const_node_group_iterator nge = mesh.node_group_end();
for (; ngi != nge; ++ngi) {
NodeGroup & ng = *(ngi->second);
std::string name = ngi->first;
NodeGroup::const_node_iterator nit = ng.begin();
NodeGroup::const_node_iterator nend = ng.end();
for (; nit != nend; ++nit) {
node_to_group[*nit].push_back(name);
}
nit = ng.begin();
if(nit != nend)
ng.empty();
}
buffer << node_to_group;
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank) continue;
AKANTU_DEBUG_INFO("Sending node groups to proc " << p
<< " TAG("<< Tag::genTag(my_rank, p, TAG_NODE_GROUP) <<")");
requests.push_back(comm.asyncSend(buffer.storage(),
buffer.getSize(),
p,
Tag::genTag(my_rank, p, TAG_NODE_GROUP)));
}
fillNodeGroupsFromBuffer(communicator, mesh, buffer);
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeNodeGroupsSlaves(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt my_rank = comm.whoAmI();
AKANTU_DEBUG_INFO("Receiving node groups from proc " << root
<< " TAG("<< Tag::genTag(root, my_rank, TAG_NODE_GROUP) <<")");
CommunicationStatus status;
comm.probe<char>(root, Tag::genTag(root, my_rank, TAG_NODE_GROUP), status);
CommunicationBuffer buffer(status.getSize());
comm.receive(buffer.storage(), buffer.getSize(), root, Tag::genTag(root, my_rank, TAG_NODE_GROUP));
fillNodeGroupsFromBuffer(communicator, mesh, buffer);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::removeElements(const Array<Element> & element_to_remove) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
std::vector<CommunicationRequest *> isend_requests;
Array<UInt> * list_of_el = new Array<UInt>[nb_proc];
// Handling ghost elements
for (UInt p = 0; p < nb_proc; ++p) {
if (p == rank) continue;
Array<Element> & recv = recv_element[p];
if(recv.getSize() == 0) continue;
Array<Element>::iterator<Element> recv_begin = recv.begin();
Array<Element>::iterator<Element> recv_end = recv.end();
Array<Element>::const_iterator<Element> er_it = element_to_remove.begin();
Array<Element>::const_iterator<Element> er_end = element_to_remove.end();
Array<UInt> & list = list_of_el[p];
for (UInt i = 0; recv_begin != recv_end; ++i, ++recv_begin) {
const Element & el = *recv_begin;
Array<Element>::const_iterator<Element> pos = std::find(er_it, er_end, el);
if(pos == er_end) {
list.push_back(i);
}
}
if(list.getSize() == recv.getSize())
list.push_back(UInt(0));
else list.push_back(UInt(-1));
AKANTU_DEBUG_INFO("Sending a message of size " << list.getSize() << " to proc " << p << " TAG(" << this->genTagFromID(0) << ")");
isend_requests.push_back(comm.asyncSend(list.storage(), list.getSize(),
p, this->genTagFromID(0)));
list.erase(list.getSize() - 1);
if (list.getSize() == recv.getSize()) continue;
Array<Element> new_recv;
for (UInt nr = 0; nr < list.getSize(); ++nr) {
Element & el = recv(list(nr));
new_recv.push_back(el);
}
AKANTU_DEBUG_INFO("I had " << recv.getSize() << " elements to recv from proc " << p << " and "
<< list.getSize() << " elements to keep. I have "
<< new_recv.getSize() << " elements left.");
recv.copy(new_recv);
}
for (UInt p = 0; p < nb_proc; ++p) {
if (p == rank) continue;
Array<Element> & send = send_element[p];
if(send.getSize() == 0) continue;
CommunicationStatus status;
AKANTU_DEBUG_INFO("Getting number of elements of proc " << p << " not needed anymore TAG("<< this->genTagFromID(0) <<")");
comm.probe<UInt>(p, this->genTagFromID(0), status);
Array<UInt> list(status.getSize());
AKANTU_DEBUG_INFO("Receiving list of elements (" << status.getSize() - 1
<< " elements) no longer needed by proc " << p
<< " TAG("<< this->genTagFromID(0) <<")");
comm.receive(list.storage(), list.getSize(),
p, this->genTagFromID(0));
if(list.getSize() == 1 && list(0) == 0) continue;
list.erase(list.getSize() - 1);
if (list.getSize() == send.getSize()) continue;
Array<Element> new_send;
for (UInt ns = 0; ns < list.getSize(); ++ns) {
Element & el = send(list(ns));
new_send.push_back(el);
}
AKANTU_DEBUG_INFO("I had " << send.getSize() << " elements to send to proc " << p << " and "
<< list.getSize() << " elements to keep. I have "
<< new_send.getSize() << " elements left.");
send.copy(new_send);
}
comm.waitAll(isend_requests);
comm.freeCommunicationRequest(isend_requests);
delete [] list_of_el;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::renumberElements(const ElementTypeMapArray<UInt> & new_numbering) {
// Handling ghost elements
for (UInt p = 0; p < nb_proc; ++p) {
if (p == rank) continue;
Array<Element> & recv = recv_element[p];
for (UInt i = 0; i < recv.getSize(); ++i) {
Element & el = recv(i);
el.element = new_numbering(el.type, el.ghost_type)(el.element);
}
Array<Element> & send = send_element[p];
for (UInt i = 0; i < send.getSize(); ++i) {
Element & el = send(i);
el.element = new_numbering(el.type, el.ghost_type)(el.element);
}
}
}
__END_AKANTU__
diff --git a/src/synchronizer/distributed_synchronizer.hh b/src/synchronizer/distributed_synchronizer.hh
index 6206401c2..053e62a85 100644
--- a/src/synchronizer/distributed_synchronizer.hh
+++ b/src/synchronizer/distributed_synchronizer.hh
@@ -1,300 +1,302 @@
/**
* @file distributed_synchronizer.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
- * @brief wrapper to the static communicator
+ * @brief Main element synchronizer
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DISTRIBUTED_SYNCHRONIZER_HH__
#define __AKANTU_DISTRIBUTED_SYNCHRONIZER_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
#include "synchronizer.hh"
#include "mesh.hh"
#include "mesh_partition.hh"
#include "communication_buffer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class DistributedSynchronizer : public Synchronizer, public MeshEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DistributedSynchronizer(Mesh & mesh,
SynchronizerID id = "distributed_synchronizer",
MemoryID memory_id = 0,
const bool register_to_event_manager = true);
public:
virtual ~DistributedSynchronizer();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get a mesh and a partition and create the local mesh and the associated
/// DistributedSynchronizer
static DistributedSynchronizer *
createDistributedSynchronizerMesh(Mesh & mesh,
const MeshPartition * partition,
UInt root = 0,
SynchronizerID id = "distributed_synchronizer",
MemoryID memory_id = 0);
/* ------------------------------------------------------------------------ */
/* Inherited from Synchronizer */
/* ------------------------------------------------------------------------ */
/// asynchronous synchronization of ghosts
void asynchronousSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
/// wait end of asynchronous synchronization of ghosts
void waitEndSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
/// build processor to element corrispondance
void buildPrankToElement();
virtual void printself(std::ostream & stream, int indent = 0) const;
/// mesh event handler onElementsChanged
virtual void onElementsChanged(const Array<Element> & old_elements_list,
const Array<Element> & new_elements_list,
const ElementTypeMapArray<UInt> & new_numbering,
const ChangedElementsEvent & event);
/// mesh event handler onRemovedElement
virtual void onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event);
/// mesh event handler onNodesAdded
virtual void onNodesAdded (const Array<UInt> & nodes_list,
const NewNodesEvent & event) {};
/// mesh event handler onRemovedNodes
virtual void onNodesRemoved(const Array<UInt> & nodes_list,
const Array<UInt> & new_numbering,
const RemovedNodesEvent & event) {};
/// mesh event handler onElementsAdded
virtual void onElementsAdded (const Array<Element> & elements_list,
const NewElementsEvent & event) {};
/// filter elements of a certain kind and copy them into a new synchronizer
void filterElementsByKind(DistributedSynchronizer * new_synchronizer,
ElementKind kind);
/// reset send and recv element lists
void reset();
/// compute buffer size for a given tag and data accessor
void computeBufferSize(DataAccessor & data_accessor, SynchronizationTag tag);
/// recalculate buffer sizes for all tags
void computeAllBufferSizes(DataAccessor & data_accessor);
/// remove elements from the synchronizer without renumbering them
void removeElements(const Array<Element> & element_to_remove);
/// renumber the elements in the synchronizer
void renumberElements(const ElementTypeMapArray<UInt> & new_numbering);
protected:
/// fill the nodes type vector
void fillNodesType(Mesh & mesh);
void fillNodesType(const MeshData & mesh_data,
DynamicCommunicationBuffer * buffers,
const std::string & tag_name,
const ElementType & el_type,
const Array<UInt> & partition_num);
template<typename T>
void fillTagBufferTemplated(const MeshData & mesh_data,
DynamicCommunicationBuffer * buffers,
const std::string & tag_name,
const ElementType & el_type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition);
void fillTagBuffer(const MeshData & mesh_data,
DynamicCommunicationBuffer * buffers,
const std::string & tag_name,
const ElementType & el_type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition);
template<typename T, typename BufferType>
void populateMeshDataTemplated(MeshData & mesh_data,
BufferType & buffer,
const std::string & tag_name,
const ElementType & el_type,
UInt nb_component,
UInt nb_local_element,
UInt nb_ghost_element);
template <typename BufferType>
void populateMeshData(MeshData & mesh_data,
BufferType & buffer,
const std::string & tag_name,
const ElementType & el_type,
const MeshDataTypeCode & type_code,
UInt nb_component,
UInt nb_local_element,
UInt nb_ghost_element);
/// fill the communications array of a distributedSynchronizer based on a partition array
void fillCommunicationScheme(const UInt * partition,
UInt nb_local_element,
UInt nb_ghost_element,
ElementType type);
/// function that handels the MeshData to be split (root side)
static void synchronizeTagsSend(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
UInt nb_tags,
const ElementType & type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition,
UInt nb_local_element,
UInt nb_ghost_element);
/// function that handles the MeshData to be split (other nodes)
static void synchronizeTagsRecv(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
UInt nb_tags,
const ElementType & type,
UInt nb_local_element,
UInt nb_ghost_element);
/// function that handles the preexisting groups in the mesh
static void synchronizeElementGroups(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
const ElementType & type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition,
UInt nb_element);
/// function that handles the preexisting groups in the mesh
static void synchronizeElementGroups(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
const ElementType & type);
template<class CommunicationBuffer>
static void fillElementGroupsFromBuffer(DistributedSynchronizer & communicator,
Mesh & mesh,
const ElementType & type,
CommunicationBuffer & buffer);
/// function that handles the preexisting groups in the mesh
static void synchronizeNodeGroupsMaster(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh);
/// function that handles the preexisting groups in the mesh
static void synchronizeNodeGroupsSlaves(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh);
template<class CommunicationBuffer>
static void fillNodeGroupsFromBuffer(DistributedSynchronizer & communicator,
Mesh & mesh,
CommunicationBuffer & buffer);
/// substitute elements in the send and recv arrays
void substituteElements(const std::map<Element, Element> & old_to_new_elements);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(PrankToElement, prank_to_element, const ElementTypeMapArray<UInt> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
enum CommTags {
TAG_SIZES = 0,
TAG_CONNECTIVITY = 1,
TAG_DATA = 2,
TAG_PARTITIONS = 3,
TAG_NB_NODES = 4,
TAG_NODES = 5,
TAG_COORDINATES = 6,
TAG_NODES_TYPE = 7,
TAG_MESH_DATA = 8,
TAG_ELEMENT_GROUP = 9,
TAG_NODE_GROUP = 10,
};
protected:
/// reference to the underlying mesh
Mesh & mesh;
std::map<SynchronizationTag, Communication> communications;
/// list of element to send to proc p
Array<Element> * send_element;
/// list of element to receive from proc p
Array<Element> * recv_element;
UInt nb_proc;
UInt rank;
friend class FilteredSynchronizer;
friend class FacetSynchronizer;
ElementTypeMapArray<UInt> prank_to_element;
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "distributed_synchronizer_tmpl.hh"
#endif /* __AKANTU_DISTRIBUTED_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/distributed_synchronizer_tmpl.hh b/src/synchronizer/distributed_synchronizer_tmpl.hh
index e561b5b5d..b8f86c05f 100644
--- a/src/synchronizer/distributed_synchronizer_tmpl.hh
+++ b/src/synchronizer/distributed_synchronizer_tmpl.hh
@@ -1,147 +1,147 @@
/**
* @file distributed_synchronizer_tmpl.hh
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue May 07 2013
- * @date last modification: Mon Jun 09 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the templated function of the DistributedSynchronizer
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DISTRIBUTED_SYNCHRONIZER_TMPL_HH__
#define __AKANTU_DISTRIBUTED_SYNCHRONIZER_TMPL_HH__
__BEGIN_AKANTU__
template<typename T>
void DistributedSynchronizer::fillTagBufferTemplated(const MeshData & mesh_data,
DynamicCommunicationBuffer * buffers,
const std::string & tag_name,
const ElementType & el_type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition) {
const Array<T> & data = mesh_data.getElementalDataArray<T>(tag_name, el_type);
// Not possible to use the iterator because it potentially triggers the creation of complex
// type templates (such as akantu::Vector< std::vector<Element> > which don't implement the right interface
// (e.g. operator<< in that case).
//typename Array<T>::template const_iterator< Vector<T> > data_it = data.begin(data.getNbComponent());
//typename Array<T>::template const_iterator< Vector<T> > data_end = data.end(data.getNbComponent());
const T * data_it = data.storage();
const T * data_end = data.storage() + data.getSize()*data.getNbComponent();
const UInt * part = partition_num.storage();
/// copying the data, element by element
for (; data_it != data_end; ++part) {
for(UInt j(0); j < data.getNbComponent(); ++j, ++data_it) {
buffers[*part] << *data_it;
}
}
data_it = data.storage();
/// copying the data for the ghost element
for (UInt el(0); data_it != data_end; data_it+=data.getNbComponent(), ++el) {
CSR<UInt>::const_iterator it = ghost_partition.begin(el);
CSR<UInt>::const_iterator end = ghost_partition.end(el);
for (;it != end; ++it) {
UInt proc = *it;
for(UInt j(0); j < data.getNbComponent(); ++j) {
buffers[proc] << data_it[j];
}
}
}
}
/* -------------------------------------------------------------------------- */
template <typename BufferType>
void DistributedSynchronizer::populateMeshData(MeshData & mesh_data,
BufferType & buffer,
const std::string & tag_name,
const ElementType & el_type,
const MeshDataTypeCode & type_code,
UInt nb_component,
UInt nb_local_element,
UInt nb_ghost_element) {
#define AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA(r, extra_param, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem) : { \
populateMeshDataTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(mesh_data, buffer, tag_name, el_type, nb_component, nb_local_element, nb_ghost_element); \
break; \
} \
switch(type_code) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA, , AKANTU_MESH_DATA_TYPES)
default : AKANTU_DEBUG_ERROR("Could not determine the type of tag" << tag_name << "!"); break;
}
#undef AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA
}
/* -------------------------------------------------------------------------- */
template<typename T, typename BufferType>
void DistributedSynchronizer::populateMeshDataTemplated(MeshData & mesh_data,
BufferType & buffer,
const std::string & tag_name,
const ElementType & el_type,
UInt nb_component,
UInt nb_local_element,
UInt nb_ghost_element) {
AKANTU_DEBUG_ASSERT(mesh.getNbElement(el_type) == nb_local_element,
"Did not got enought informations for the tag " << tag_name <<
" and the element type " << el_type << ":" << "_not_ghost." <<
" Got " << nb_local_element << " values, expected " << mesh.getNbElement(el_type));
mesh_data.registerElementalData<T>(tag_name);
Array<T> & data = mesh_data.getElementalDataArrayAlloc<T>(tag_name, el_type, _not_ghost, nb_component);
data.resize(nb_local_element);
/// unpacking the data, element by element
for (UInt i(0); i < nb_local_element; ++i) {
for(UInt j(0); j < nb_component; ++j) {
buffer >> data(i,j);
}
}
AKANTU_DEBUG_ASSERT(mesh.getNbElement(el_type, _ghost) == nb_ghost_element,
"Did not got enought informations for the tag " << tag_name <<
" and the element type " << el_type << ":" << "_ghost." <<
" Got " << nb_ghost_element << " values, expected " <<
mesh.getNbElement(el_type, _ghost));
mesh_data.registerElementalData<T>(tag_name);
Array<T> & data_ghost = mesh_data.getElementalDataArrayAlloc<T>(tag_name, el_type, _ghost, nb_component);
data_ghost.resize(nb_ghost_element);
/// unpacking the ghost data, element by element
for (UInt j(0); j < nb_ghost_element; ++j) {
for(UInt k(0); k < nb_component; ++k) {
buffer >> data_ghost(j, k);
}
}
}
__END_AKANTU__
#endif /* __AKANTU_DISTRIBUTED_SYNCHRONIZER_TMPL_HH__ */
diff --git a/src/synchronizer/dof_synchronizer.cc b/src/synchronizer/dof_synchronizer.cc
index 6375af800..236935486 100644
--- a/src/synchronizer/dof_synchronizer.cc
+++ b/src/synchronizer/dof_synchronizer.cc
@@ -1,501 +1,502 @@
/**
* @file dof_synchronizer.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Fri Jun 17 2011
- * @date last modification: Thu Mar 27 2014
+ * @date last modification: Wed Oct 21 2015
*
* @brief DOF synchronizing object implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "dof_synchronizer.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/**
* A DOFSynchronizer needs a mesh and the number of degrees of freedom
* per node to be created. In the constructor computes the local and global dof
* number for each dof. The member
* proc_informations (std vector) is resized with the number of mpi
* processes. Each entry in the vector is a PerProcInformations object
* that contains the interactions of the current mpi process (prank) with the
* mpi process corresponding to the position of that entry. Every
* ProcInformations object contains one array with the dofs that have
* to be sent to prank and a second one with dofs that willl be received form prank.
* This information is needed for the asychronous communications. The
* constructor sets up this information.
* @param mesh mesh discretizing the domain we want to analyze
* @param nb_degree_of_freedom number of degrees of freedom per node
*/
DOFSynchronizer::DOFSynchronizer(const Mesh & mesh, UInt nb_degree_of_freedom) :
global_dof_equation_numbers(0, 1, "global_equation_number"),
local_dof_equation_numbers(0, 1, "local_equation_number"),
dof_global_ids(0, 1, "global_ids"),
dof_types(0, 1, "types") {
gather_scatter_scheme_initialized = false;
prank = static_communicator->whoAmI();
psize = static_communicator->getNbProc();
proc_informations.resize(psize);
UInt nb_nodes = mesh.getNbNodes();
nb_dofs = nb_nodes * nb_degree_of_freedom;
dof_global_ids.resize(nb_dofs);
dof_types.resize(nb_dofs);
nb_global_dofs = mesh.getNbGlobalNodes() * nb_degree_of_freedom;
/// compute the global id for each dof and store the dof type (pure ghost, slave, master or local)
UInt * dof_global_id = dof_global_ids.storage();
Int * dof_type = dof_types.storage();
for(UInt n = 0, ld = 0; n < nb_nodes; ++n) {
UInt node_global_id = mesh.getNodeGlobalId(n);
UInt node_type = mesh.getNodeType(n);
for (UInt d = 0; d < nb_degree_of_freedom; ++d, ++ld) {
*dof_global_id = node_global_id * nb_degree_of_freedom + d;
global_dof_to_local[*dof_global_id] = ld;
*(dof_type++) = node_type;
dof_global_id++;
}
}
if(psize == 1) return;
/// creating communication scheme
dof_global_id = dof_global_ids.storage();
dof_type = dof_types.storage();
for (UInt n = 0; n < nb_dofs; ++n) {
/// check if dof is slave. In that case the value stored in
/// dof_type corresponds to the process that has the corresponding
/// master dof
if(*dof_type >= 0) {
/// has to receive n from proc[*dof_type]
proc_informations[*dof_type].master_dofs.push_back(n);
}
dof_type++;
}
/// at this point the master nodes in PerProcInfo are known
/// exchanging information
for (UInt p = 1; p < psize; ++p) {
UInt sendto = (psize + prank + p) % psize;
UInt recvfrom = (psize + prank - p) % psize;
/// send the master nodes
UInt nb_master_dofs = proc_informations[sendto].master_dofs.getSize();
UInt * master_dofs = proc_informations[sendto].master_dofs.storage();
UInt * send_buffer = new UInt[nb_master_dofs];
for (UInt d = 0; d < nb_master_dofs; ++d) {
send_buffer[d] = dof_global_id[master_dofs[d]];
}
UInt nb_slave_dofs = 0;
UInt * recv_buffer;
std::vector<CommunicationRequest *> requests;
requests.push_back(static_communicator->asyncSend(&nb_master_dofs, 1, sendto, 0));
if(nb_master_dofs != 0) {
AKANTU_DEBUG(dblInfo, "Sending "<< nb_master_dofs << " dofs to " << sendto);
requests.push_back(static_communicator->asyncSend(send_buffer, nb_master_dofs, sendto, 1));
}
/// Receive the info and store them as slave nodes
static_communicator->receive(&nb_slave_dofs, 1, recvfrom, 0);
if(nb_slave_dofs != 0) {
AKANTU_DEBUG(dblInfo, "Receiving "<< nb_slave_dofs << " dofs from " << recvfrom);
proc_informations[recvfrom].slave_dofs.resize(nb_slave_dofs);
recv_buffer = proc_informations[recvfrom].slave_dofs.storage();
static_communicator->receive(recv_buffer, nb_slave_dofs, recvfrom, 1);
}
for (UInt d = 0; d < nb_slave_dofs; ++d) {
recv_buffer[d] = global_dof_to_local[recv_buffer[d]];
}
static_communicator->waitAll(requests);
static_communicator->freeCommunicationRequest(requests);
requests.clear();
delete [] send_buffer;
}
}
/* -------------------------------------------------------------------------- */
DOFSynchronizer::~DOFSynchronizer() {
}
/* -------------------------------------------------------------------------- */
void DOFSynchronizer::initLocalDOFEquationNumbers() {
AKANTU_DEBUG_IN();
local_dof_equation_numbers.resize(nb_dofs);
Int * dof_equation_number = local_dof_equation_numbers.storage();
for (UInt d = 0; d < nb_dofs; ++d) {
*(dof_equation_number++) = d;
}
//local_dof_equation_numbers.resize(nb_dofs);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DOFSynchronizer::asynchronousSynchronize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
if (communications.find(tag) == communications.end())
computeBufferSize(data_accessor, tag);
Communication & communication = communications[tag];
AKANTU_DEBUG_ASSERT(communication.send_requests.size() == 0,
"There must be some pending sending communications. Tag is " << tag);
std::map<SynchronizationTag, UInt>::iterator t_it = tag_counter.find(tag);
UInt counter = 0;
if(t_it == tag_counter.end()) {
tag_counter[tag] = 0;
} else {
counter = ++(t_it->second);
}
for (UInt p = 0; p < psize; ++p) {
UInt ssize = communication.size_to_send[p];
if(p == prank || ssize == 0) continue;
CommunicationBuffer & buffer = communication.send_buffer[p];
buffer.resize(ssize);
#ifndef AKANTU_NDEBUG
UInt nb_dofs = proc_informations[p].slave_dofs.getSize();
AKANTU_DEBUG_INFO("Packing data for proc " << p
<< " (" << ssize << "/" << nb_dofs
<<" data to send/dofs)");
/// pack global equation numbers in debug mode
Array<UInt>::const_iterator<UInt> bit = proc_informations[p].slave_dofs.begin();
Array<UInt>::const_iterator<UInt> bend = proc_informations[p].slave_dofs.end();
for (; bit != bend; ++bit) {
buffer << global_dof_equation_numbers[*bit];
}
#endif
/// dof synchronizer needs to send the data corresponding to the
data_accessor.packDOFData(buffer, proc_informations[p].slave_dofs, tag);
AKANTU_DEBUG_ASSERT(buffer.getPackedSize() == ssize,
"a problem has been introduced with "
<< "false sent sizes declaration "
<< buffer.getPackedSize() << " != " << ssize);
AKANTU_DEBUG_INFO("Posting send to proc " << p
<< " (tag: " << tag << " - " << ssize << " data to send)"
<< " [" << Tag::genTag(prank, counter, tag) << "]");
communication.send_requests.push_back(static_communicator->asyncSend(buffer.storage(),
ssize,
p,
Tag::genTag(prank, counter, tag)));
}
AKANTU_DEBUG_ASSERT(communication.recv_requests.size() == 0,
"There must be some pending receive communications");
for (UInt p = 0; p < psize; ++p) {
UInt rsize = communication.size_to_receive[p];
if(p == prank || rsize == 0) continue;
CommunicationBuffer & buffer = communication.recv_buffer[p];
buffer.resize(rsize);
AKANTU_DEBUG_INFO("Posting receive from proc " << p
<< " (tag: " << tag << " - " << rsize << " data to receive) "
<< " [" << Tag::genTag(p, counter, tag) << "]");
communication.recv_requests.push_back(static_communicator->asyncReceive(buffer.storage(),
rsize,
p,
Tag::genTag(p, counter, tag)));
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DOFSynchronizer::waitEndSynchronize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(communications.find(tag) != communications.end(), "No communication with the tag \""
<< tag <<"\" started");
Communication & communication = communications[tag];
std::vector<CommunicationRequest *> req_not_finished;
std::vector<CommunicationRequest *> * req_not_finished_tmp = &req_not_finished;
std::vector<CommunicationRequest *> * recv_requests_tmp = &(communication.recv_requests);
// static_communicator->waitAll(recv_requests);
while(!recv_requests_tmp->empty()) {
for (std::vector<CommunicationRequest *>::iterator req_it = recv_requests_tmp->begin();
req_it != recv_requests_tmp->end() ; ++req_it) {
CommunicationRequest * req = *req_it;
if(static_communicator->testRequest(req)) {
UInt proc = req->getSource();
AKANTU_DEBUG_INFO("Unpacking data coming from proc " << proc);
CommunicationBuffer & buffer = communication.recv_buffer[proc];
#ifndef AKANTU_NDEBUG
Array<UInt>::const_iterator<UInt> bit = proc_informations[proc].master_dofs.begin();
Array<UInt>::const_iterator<UInt> bend = proc_informations[proc].master_dofs.end();
for (; bit != bend; ++bit) {
Int global_dof_eq_nb_loc = global_dof_equation_numbers[*bit];
Int global_dof_eq_nb = 0;
buffer >> global_dof_eq_nb;
Real tolerance = Math::getTolerance();
if(std::abs(global_dof_eq_nb - global_dof_eq_nb_loc) <= tolerance) continue;
AKANTU_DEBUG_ERROR("Unpacking an unknown global dof equation number for dof: "
<< *bit
<< "(global dof equation number = " << global_dof_eq_nb
<< " and buffer = " << global_dof_eq_nb << ") ["
<< std::abs(global_dof_eq_nb - global_dof_eq_nb_loc)
<< "] - tag: " << tag);
}
#endif
data_accessor.unpackDOFData(buffer, proc_informations[proc].master_dofs, tag);
buffer.resize(0);
AKANTU_DEBUG_ASSERT(buffer.getLeftToUnpack() == 0,
"all data have not been unpacked: "
<< buffer.getLeftToUnpack() << " bytes left");
static_communicator->freeCommunicationRequest(req);
} else {
req_not_finished_tmp->push_back(req);
}
}
std::vector<CommunicationRequest *> * swap = req_not_finished_tmp;
req_not_finished_tmp = recv_requests_tmp;
recv_requests_tmp = swap;
req_not_finished_tmp->clear();
}
AKANTU_DEBUG_INFO("Waiting that every send requests are received");
static_communicator->waitAll(communication.send_requests);
for (std::vector<CommunicationRequest *>::iterator req_it = communication.send_requests.begin();
req_it != communication.send_requests.end() ; ++req_it) {
CommunicationRequest & req = *(*req_it);
if(static_communicator->testRequest(&req)) {
UInt proc = req.getDestination();
CommunicationBuffer & buffer = communication.send_buffer[proc];
buffer.resize(0);
static_communicator->freeCommunicationRequest(&req);
}
}
communication.send_requests.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* This function computes the buffer size needed for in order to send data or receive data.
* @param data_accessor object of a class that needs to use the DOFSynchronizer. This class has to inherit from the * DataAccessor interface.
* @param tag synchronization tag: indicates what variable should be sychronized, e.g. mass, nodal residual, etc.
* for the SolidMechanicsModel
*/
void DOFSynchronizer::computeBufferSize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
communications[tag].resize(psize);
for (UInt p = 0; p < psize; ++p) {
/// initialize the size of data that we be sent and received
UInt ssend = 0;
UInt sreceive = 0;
if(p != prank) {
/// check if processor prank has to send dof information to p
if(proc_informations[p].slave_dofs.getSize() != 0) {
#ifndef AKANTU_NDEBUG
/// in debug mode increase buffer size to send the positions
/// of nodes in the direction that correspond to the dofs
ssend += proc_informations[p].slave_dofs.getSize() * sizeof(Int);
#endif
ssend += data_accessor.getNbDataForDOFs(proc_informations[p].slave_dofs, tag);
AKANTU_DEBUG_INFO("I have " << ssend << "(" << ssend / 1024.
<< "kB - "<< proc_informations[p].slave_dofs.getSize() <<" dof(s)) data to send to " << p << " for tag "
<< tag);
}
/// check if processor prank has to receive dof information from p
if(proc_informations[p].master_dofs.getSize() != 0) {
#ifndef AKANTU_NDEBUG
/// in debug mode increase buffer size to receive the
/// positions of nodes in the direction that correspond to the
/// dofs
sreceive += proc_informations[p].master_dofs.getSize() * sizeof(Int);
#endif
sreceive += data_accessor.getNbDataForDOFs(proc_informations[p].master_dofs, tag);
AKANTU_DEBUG_INFO("I have " << sreceive << "(" << sreceive / 1024.
<< "kB - "<< proc_informations[p].master_dofs.getSize() <<" dof(s)) data to receive for tag "
<< tag);
}
}
communications[tag].size_to_send [p] = ssend;
communications[tag].size_to_receive[p] = sreceive;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DOFSynchronizer::initGlobalDOFEquationNumbers() {
AKANTU_DEBUG_IN();
global_dof_equation_numbers.resize(nb_dofs);
Int * dof_type = dof_types.storage();
UInt * dof_global_id = dof_global_ids.storage();
Int * dof_equation_number = global_dof_equation_numbers.storage();
for(UInt d = 0; d < nb_dofs; ++d) {
/// if ghost dof the equation_number is greater than nb_global_dofs
Int global_eq_num = *dof_global_id + (*dof_type > -3 ? 0 : nb_global_dofs);
*(dof_equation_number) = global_eq_num;
global_dof_equation_number_to_local[global_eq_num] = d;
dof_equation_number++;
dof_global_id++;
dof_type++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DOFSynchronizer::initScatterGatherCommunicationScheme() {
AKANTU_DEBUG_IN();
if(psize == 1 || gather_scatter_scheme_initialized) {
if(psize == 1) gather_scatter_scheme_initialized = true;
AKANTU_DEBUG_OUT();
return;
}
/// creating communication scheme
UInt * dof_global_id = dof_global_ids.storage();
Int * dof_type = dof_types.storage();
Array<UInt> * local_dofs = new Array<UInt>(0,2);
UInt local_dof_val[2];
nb_needed_dofs = 0;
nb_local_dofs = 0;
for (UInt n = 0; n < nb_dofs; ++n) {
if(*dof_type != -3) {
local_dof_val[0] = *dof_global_id;
if(*dof_type == -1 || *dof_type == -2) {
local_dof_val[1] = 0; // master for this node, shared or not
nb_local_dofs++;
} else if (*dof_type >= 0) {
nb_needed_dofs++;
local_dof_val[1] = 1; // slave node
}
local_dofs->push_back(local_dof_val);
}
dof_type++;
dof_global_id++;
}
Int * nb_dof_per_proc = new Int[psize];
nb_dof_per_proc[prank] = local_dofs->getSize();
static_communicator->allGather(nb_dof_per_proc, 1);
AKANTU_DEBUG(dblDebug, "I have " << local_dofs->getSize() << " not ghost dofs ("
<< nb_local_dofs << " local and " << nb_needed_dofs << " slave)");
UInt pos = 0;
for (UInt p = 0; p < prank; ++p) pos += nb_dof_per_proc[p];
UInt nb_total_dofs = pos;
for (UInt p = prank; p < psize; ++p) nb_total_dofs += nb_dof_per_proc[p];
int * nb_values = new int[psize];
for (unsigned int p = 0; p < psize; ++p) nb_values[p] = nb_dof_per_proc[p] * 2;
UInt * buffer = new UInt[2*nb_total_dofs];
memcpy(buffer + 2 * pos, local_dofs->storage(), local_dofs->getSize() * 2 * sizeof(UInt));
delete local_dofs;
static_communicator->allGatherV(buffer, nb_values);
UInt * tmp_buffer = buffer;
for (UInt p = 0; p < psize; ++p) {
UInt proc_p_nb_dof = nb_dof_per_proc[p];
if (p != prank){
AKANTU_DEBUG(dblDebug, "I get " << proc_p_nb_dof << "(" << nb_values[p] << ") dofs from " << p + 1);
proc_informations[p].dofs.resize(0);
for (UInt dd = 0; dd < proc_p_nb_dof; ++dd) {
UInt dof = tmp_buffer[2*dd];
if(tmp_buffer[2*dd + 1] == 0)
proc_informations[p].dofs.push_back(dof);
else
proc_informations[p].needed_dofs.push_back(dof);
}
AKANTU_DEBUG(dblDebug, "Proc " << p + 1 << " sends me "
<< proc_informations[p].dofs.getSize() << " local dofs, and "
<< proc_informations[p].needed_dofs.getSize() << " slave dofs");
}
tmp_buffer += 2*proc_p_nb_dof;
}
delete [] nb_dof_per_proc;
delete [] buffer;
delete [] nb_values;
gather_scatter_scheme_initialized = true;
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/synchronizer/dof_synchronizer.hh b/src/synchronizer/dof_synchronizer.hh
index 435f246c1..90acb22ef 100644
--- a/src/synchronizer/dof_synchronizer.hh
+++ b/src/synchronizer/dof_synchronizer.hh
@@ -1,244 +1,245 @@
/**
* @file dof_synchronizer.hh
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Fri Jun 17 2011
- * @date last modification: Fri Mar 21 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief Synchronize Array of DOFs
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_array.hh"
#include "static_communicator.hh"
#include "synchronizer.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DOF_SYNCHRONIZER_HH__
#define __AKANTU_DOF_SYNCHRONIZER_HH__
__BEGIN_AKANTU__
class Mesh;
template<typename T>
class AddOperation {
public:
inline T operator()(T & b, T & a) { return a + b; };
};
class DOFSynchronizer : public Synchronizer {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DOFSynchronizer(const Mesh & mesh, UInt nb_degree_of_freedom);
virtual ~DOFSynchronizer();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// asynchronous synchronization of ghosts
virtual void asynchronousSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
/// wait end of asynchronous synchronization of ghosts
virtual void waitEndSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
/// compute buffer size for a given tag and data accessor
virtual void computeBufferSize(DataAccessor & data_accessor, SynchronizationTag tag);
/// init the scheme for scatter and gather operation, need extra memory
void initScatterGatherCommunicationScheme();
/// initialize the equation number with local ids
void initLocalDOFEquationNumbers();
/// initialize the equation number with local ids
void initGlobalDOFEquationNumbers();
/**
* Gather the DOF value on the root proccessor
*
* @param to_gather data to gather
* @param root processor on which data are gathered
* @param gathered Array containing the gathered data, only valid on root processor
*/
template<typename T>
/// Gather the DOF value on the root proccessor
void gather(const Array<T> & to_gather, UInt root,
Array<T> * gathered = NULL) const;
/**
* Scatter a DOF Array form root to all processors
*
* @param scattered data to scatter, only valid on root processor
* @param root processor scattering data
* @param to_scatter result of scattered data
*/
template<typename T>
/// Scatter a DOF Array form root to all processors
void scatter(Array<T> & scattered, UInt root,
const Array<T> * to_scatter = NULL) const;
template<typename T> void synchronize(Array<T> & vector) const ;
template<template <class> class Op, typename T> void reduceSynchronize(Array<T> & vector) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the equation_number Array
AKANTU_GET_MACRO(LocalDOFEquationNumbers, local_dof_equation_numbers, const Array<Int> &);
AKANTU_GET_MACRO(GlobalDOFEquationNumbers, global_dof_equation_numbers, const Array<Int> &);
Array<Int> * getLocalDOFEquationNumbersPointer(){return &local_dof_equation_numbers;};
Array<Int> * getGlobalDOFEquationNumbersPointer(){return &global_dof_equation_numbers;};
typedef unordered_map<Int, UInt>::type GlobalEquationNumberMap;
AKANTU_GET_MACRO(GlobalEquationNumberToLocal, global_dof_equation_number_to_local, const GlobalEquationNumberMap &)
/// get the Array of global ids of the dofs
AKANTU_GET_MACRO(DOFGlobalIDs, dof_global_ids, const Array<UInt> &);
/// get the global id of a dof
inline UInt getDOFGlobalID(UInt local_id) const {
return dof_global_ids(local_id);
}
/// get the local id of a global dof
inline UInt getDOFLocalID(UInt global_id) const {
return global_dof_to_local.find(global_id)->second;
}
/// get the DOF type Array
AKANTU_GET_MACRO(DOFTypes, dof_types, const Array<Int> &);
AKANTU_GET_MACRO(NbDOFs, nb_dofs, UInt);
AKANTU_GET_MACRO(NbGlobalDOFs, nb_global_dofs, UInt);
/// say if a node is a pure ghost node
inline bool isPureGhostDOF(UInt n) const;
/// say if a node is pure local or master node
inline bool isLocalOrMasterDOF(UInt n) const;
/// say if a node is pure local
inline bool isLocalDOF(UInt n) const;
/// say if a node is a master node
inline bool isMasterDOF(UInt n) const;
/// say if a node is a slave node
inline bool isSlaveDOF(UInt n) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// equation number position where a dof is synchronized in the matrix (by default = global id)
Array<Int> global_dof_equation_numbers;
Array<Int> local_dof_equation_numbers;
GlobalEquationNumberMap global_dof_equation_number_to_local;
/// DOF global id
Array<UInt> dof_global_ids;
/*
* DOF type -3 pure ghost, -2 master for the dof, -1 normal dof, i in
* [0-N] slave dof and master is proc i
*/
Array<Int> dof_types;
/// number of dofs
UInt nb_dofs;
UInt nb_global_dofs;
unordered_map<UInt, UInt>::type global_dof_to_local;
UInt prank;
UInt psize;
struct PerProcInformations {
/// dofs to send to the proc
Array<UInt> slave_dofs;
/// dofs to recvs from the proc
Array<UInt> master_dofs;
/* ---------------------------------------------------------------------- */
/* Data for gather/scatter */
/* ---------------------------------------------------------------------- */
/// the dof that the node handle
Array<UInt> dofs;
/// the dof that the proc need
Array<UInt> needed_dofs;
};
std::vector<PerProcInformations> proc_informations;
/// nb dofs with type -1 or -2
UInt nb_local_dofs;
/// nb dof with type >= 0
UInt nb_needed_dofs;
bool gather_scatter_scheme_initialized;
std::map<SynchronizationTag, Communication> communications;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "dof_synchronizer_inline_impl.cc"
#endif
/// standard output stream operator
// inline std::ostream & operator <<(std::ostream & stream, const DOFSynchronizer & _this)
// {
// _this.printself(stream);
// return stream;
// }
__END_AKANTU__
#endif /* __AKANTU_DOF_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/dof_synchronizer_inline_impl.cc b/src/synchronizer/dof_synchronizer_inline_impl.cc
index ee040e3b4..0b8a965b1 100644
--- a/src/synchronizer/dof_synchronizer_inline_impl.cc
+++ b/src/synchronizer/dof_synchronizer_inline_impl.cc
@@ -1,315 +1,317 @@
/**
* @file dof_synchronizer_inline_impl.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Tue Dec 09 2014
*
* @brief DOFSynchronizer inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<typename T> void DOFSynchronizer::gather(const Array<T> & to_gather, UInt root,
Array<T> * gathered) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(gather_scatter_scheme_initialized == true, "You should call initScatterGatherCommunicationScheme before trying to gather a Array !!");
if(psize == 1) {
gathered->copy(to_gather, true);
AKANTU_DEBUG_OUT();
return;
}
UInt * dof_global_id = dof_global_ids.storage();
Int * dof_type = dof_types.storage();
T * to_gather_val = to_gather.storage();
T * buffer;
if(prank == root) {
gathered->resize(nb_global_dofs / gathered->getNbComponent());
buffer = gathered->storage();
} else
buffer = new T[nb_local_dofs];
UInt dof = 0;
for (UInt d = 0; d < nb_dofs; ++d) {
if(*dof_type != -3) {
if(*dof_type == -1 || *dof_type == -2) {
if (prank == root) dof = *dof_global_id;
buffer[dof++] = *to_gather_val;
}
}
dof_type++;
dof_global_id++;
to_gather_val++;
}
if (prank == root) {
for (UInt p = 0; p < psize; ++p) {
if(p == root) continue;
UInt nb_dofs = proc_informations[p].dofs.getSize();
AKANTU_DEBUG_INFO("Gather - Receiving " << nb_dofs << " from " << p);
if(nb_dofs) {
buffer = new T[nb_dofs];
static_communicator->receive(buffer, nb_dofs, p, 0);
T * buffer_tmp = buffer;
UInt * remote_dofs = proc_informations[p].dofs.storage();
for (UInt d = 0; d < nb_dofs; ++d) {
gathered->storage()[*remote_dofs++] = *(buffer_tmp++);
}
delete [] buffer;
}
}
} else {
AKANTU_DEBUG_INFO("Gather - Sending " << nb_local_dofs << " to " << root);
if(nb_local_dofs)
static_communicator->send(buffer, nb_local_dofs, root, 0);
delete [] buffer;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T> void DOFSynchronizer::scatter(Array<T> & scattered, UInt root,
const Array<T> * to_scatter) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(gather_scatter_scheme_initialized == true, "You should call initScatterGatherCommunicationScheme before trying to scatter a Array !!");
if(psize == 1) {
scattered.copy(*to_scatter, true);
AKANTU_DEBUG_OUT();
return;
}
scattered.resize(nb_dofs / scattered.getNbComponent());
UInt * dof_global_id = dof_global_ids.storage();
Int * dof_type = dof_types.storage();
if (prank == root) {
for (UInt p = 0; p < psize; ++p) {
if(p == root) continue;
UInt nb_needed_dof = proc_informations[p].needed_dofs.getSize();
UInt nb_local_dof = proc_informations[p].dofs.getSize();
AKANTU_DEBUG_INFO("Scatter - Sending " << nb_local_dof + nb_needed_dof << " to " << p);
if(nb_local_dof + nb_needed_dof) {
T * send_buffer = new T[nb_local_dof + nb_needed_dof];
T * buffer_tmp = send_buffer;
UInt * remote_dofs = proc_informations[p].dofs.storage();
for (UInt d = 0; d < nb_local_dof; ++d) {
*(buffer_tmp++) = to_scatter->storage()[*remote_dofs++];
}
remote_dofs = proc_informations[p].needed_dofs.storage();
for (UInt d = 0; d < nb_needed_dof; ++d) {
*(buffer_tmp++) = to_scatter->storage()[*remote_dofs++];
}
static_communicator->send(send_buffer, nb_local_dof + nb_needed_dof, p, 0);
delete [] send_buffer;
}
}
T * scattered_val = scattered.storage();
for (UInt d = 0; d < nb_dofs; ++d) {
if(*dof_type != -3) {
if(*dof_type >= -2)
*scattered_val = to_scatter->storage()[*dof_global_id];
}
scattered_val++;
dof_type++;
dof_global_id++;
}
} else {
T * buffer;
AKANTU_DEBUG_INFO("Scatter - Receiving " << nb_dofs << " from " << root);
if(nb_local_dofs + nb_needed_dofs) {
buffer = new T[nb_local_dofs + nb_needed_dofs];
static_communicator->receive(buffer, nb_local_dofs + nb_needed_dofs, root, 0);
T * scattered_val = scattered.storage();
UInt local_dofs = 0;
UInt needed_dofs = nb_local_dofs;
for (UInt d = 0; d < nb_dofs; ++d) {
if(*dof_type != -3) {
if(*dof_type == -1 || *dof_type == -2)
*scattered_val = buffer[local_dofs++];
else if(*dof_type >= 0)
*scattered_val = buffer[needed_dofs++];
}
scattered_val++;
dof_type++;
}
delete [] buffer;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T> void DOFSynchronizer::synchronize(Array<T> & dof_vector) const {
AKANTU_DEBUG_IN();
if(psize == 1) {
AKANTU_DEBUG_OUT();
return;
}
for (UInt p = 1; p < psize; ++p) {
UInt sendto = (psize + prank + p) % psize;
UInt recvfrom = (psize + prank - p) % psize;
UInt nb_slave_dofs = proc_informations[sendto].slave_dofs.getSize();
UInt * slave_dofs = proc_informations[sendto].slave_dofs.storage();
UInt nb_master_dofs = proc_informations[recvfrom].master_dofs.getSize();
UInt * master_dofs = proc_informations[recvfrom].master_dofs.storage();
T * send_buffer = new T[nb_slave_dofs];
T * recv_buffer = new T[nb_master_dofs];
for (UInt d = 0; d < nb_slave_dofs; ++d) {
AKANTU_DEBUG_ASSERT(dof_types(slave_dofs[d]) == -2,
"Sending node " << slave_dofs[d]
<< "(gid" << dof_global_ids(d) << ") to proc "
<< sendto << " but it is not a master node.");
send_buffer[d] = dof_vector.storage()[slave_dofs[d]];
}
/// ring blocking communications
CommunicationRequest * request = NULL;
if(nb_slave_dofs != 0) request = static_communicator->asyncSend(send_buffer, nb_slave_dofs, sendto , 0);
if(nb_master_dofs != 0) static_communicator->receive(recv_buffer, nb_master_dofs, recvfrom, 0);
for (UInt d = 0; d < nb_master_dofs; ++d) {
AKANTU_DEBUG_ASSERT(dof_types(master_dofs[d]) >= 0,
"Received node " << master_dofs[d]
<< "(gid" << dof_global_ids(d) << ") from proc "
<< recvfrom << " but it is not a slave node.");
dof_vector.storage()[master_dofs[d]] = recv_buffer[d];
}
if(nb_slave_dofs != 0) {
static_communicator->wait(request);
static_communicator->freeCommunicationRequest(request);
}
delete [] send_buffer;
delete [] recv_buffer;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <class> class Op, typename T> void DOFSynchronizer::reduceSynchronize(Array<T> & dof_vector) const {
AKANTU_DEBUG_IN();
if(psize == 1) {
AKANTU_DEBUG_OUT();
return;
}
for (UInt p = 1; p < psize; ++p) {
UInt sendto = (psize + prank + p) % psize;
UInt recvfrom = (psize + prank - p) % psize;
UInt nb_slave_dofs = proc_informations[recvfrom].slave_dofs.getSize();
UInt * slave_dofs = proc_informations[recvfrom].slave_dofs.storage();
UInt nb_master_dofs = proc_informations[sendto].master_dofs.getSize();
UInt * master_dofs = proc_informations[sendto].master_dofs.storage();
T * send_buffer = new T[nb_master_dofs];
T * recv_buffer = new T[nb_slave_dofs];
for (UInt d = 0; d < nb_master_dofs; ++d) {
send_buffer[d] = dof_vector.storage()[master_dofs[d]];
}
CommunicationRequest * request = NULL;
if(nb_master_dofs != 0) request = static_communicator->asyncSend(send_buffer, nb_master_dofs, sendto , 0);
if(nb_slave_dofs != 0) static_communicator->receive(recv_buffer, nb_slave_dofs, recvfrom, 0);
Op<T> oper;
for (UInt d = 0; d < nb_slave_dofs; ++d) {
dof_vector.storage()[slave_dofs[d]] = oper(dof_vector.storage()[slave_dofs[d]], recv_buffer[d]);
}
if(nb_master_dofs != 0) {
static_communicator->wait(request);
static_communicator->freeCommunicationRequest(request);
}
delete [] send_buffer;
delete [] recv_buffer;
}
synchronize(dof_vector);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isPureGhostDOF(UInt n) const {
return dof_types.getSize() ? (dof_types(n) == -3) : false;
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isLocalOrMasterDOF(UInt n) const {
return dof_types.getSize() ? (dof_types(n) == -2) || (dof_types(n) == -1) : true;
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isLocalDOF(UInt n) const {
return dof_types.getSize() ? dof_types(n) == -1 : true;
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isMasterDOF(UInt n) const {
return dof_types.getSize() ? dof_types(n) == -2 : false;
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isSlaveDOF(UInt n) const {
return dof_types.getSize() ? dof_types(n) >= 0 : false;
}
diff --git a/src/synchronizer/filtered_synchronizer.cc b/src/synchronizer/filtered_synchronizer.cc
index d1aa14f17..eaa672422 100644
--- a/src/synchronizer/filtered_synchronizer.cc
+++ b/src/synchronizer/filtered_synchronizer.cc
@@ -1,197 +1,197 @@
/**
* @file filtered_synchronizer.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Mathilde Radiguet <mathilde.radiguet@epfl.ch>
*
* @date creation: Wed Sep 18 2013
- * @date last modification: Mon Aug 25 2014
+ * @date last modification: Sat Jul 11 2015
*
* @brief filtered synchronizer
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "filtered_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
FilteredSynchronizer::FilteredSynchronizer(Mesh & mesh,
SynchronizerID id,
MemoryID memory_id) :
DistributedSynchronizer(mesh, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
FilteredSynchronizer * FilteredSynchronizer::
createFilteredSynchronizer(const DistributedSynchronizer & d_synchronizer,
SynchElementFilter & filter) {
AKANTU_DEBUG_IN();
FilteredSynchronizer & f_synchronizer =
*(new FilteredSynchronizer(d_synchronizer.mesh,
d_synchronizer.id + ":filtered",
d_synchronizer.memory_id));
f_synchronizer.setupSynchronizer(d_synchronizer,
filter);
AKANTU_DEBUG_OUT();
return &f_synchronizer;
}
/* -------------------------------------------------------------------------- */
void FilteredSynchronizer::setupSynchronizer(const DistributedSynchronizer & d_synchronizer,
SynchElementFilter & filter) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Array<Element> * d_send_element = d_synchronizer.send_element;
Array<Element> * d_recv_element = d_synchronizer.recv_element;
std::vector<CommunicationRequest *> isend_requests;
Array<UInt> ** keep_element_recv = new Array<UInt>*[this->nb_proc];
// loop over procs
for (UInt p = 0; p < this->nb_proc; ++p) {
keep_element_recv[p] = NULL;
if (p == this->rank) continue;
// access the element for this proc
const Array<Element> & unfiltered_elements = d_recv_element[p];
Array<Element> & filtered_elements = recv_element[p];
if (unfiltered_elements.getSize() == 0) continue;
keep_element_recv[p] = new Array<UInt>(0,1,"keep_element_recv");
// iterator to loop over all source elements
Array<Element>::const_iterator<Element> it = unfiltered_elements.begin();
Array<Element>::const_iterator<Element> end = unfiltered_elements.end();
// if filter accepts this element, push it into the destination elements
for (UInt el=0; it != end; ++it, ++el) {
const Element & element = *it;
if (filter(element)) {
filtered_elements.push_back(element);
keep_element_recv[p]->push_back(el);
}
}
keep_element_recv[p]->push_back(-1); // just to be sure to send
// something due to some shitty
// MPI implementation who do not
// know what to do with a 0 size
// send
AKANTU_DEBUG_INFO("I have " << keep_element_recv[p]->getSize() - 1
<< " elements to still receive from processor " << p
<< " (communication tag : "
<< Tag::genTag(this->rank, 0, RECEIVE_LIST_TAG) << ")");
isend_requests.push_back(comm.asyncSend<UInt>(keep_element_recv[p]->storage(),
keep_element_recv[p]->getSize(),
p,
Tag::genTag(this->rank, 0, RECEIVE_LIST_TAG)));
}
for (UInt p = 0; p < this->nb_proc; ++p) {
if (p == this->rank) continue;
const Array<Element> & unfiltered_elements = d_send_element[p];
Array<Element> & filtered_elements = send_element[p];
if (unfiltered_elements.getSize() == 0) continue;
AKANTU_DEBUG_INFO("Waiting list of elements to keep from processor " << p
<< " (communication tag : "
<< Tag::genTag(p, 0, RECEIVE_LIST_TAG) << ")");
CommunicationStatus status;
comm.probe<UInt>(p, Tag::genTag(p, 0, RECEIVE_LIST_TAG), status);
Array<UInt> keep_element(status.getSize(),1,"keep_element_snd");
AKANTU_DEBUG_INFO("I have " << keep_element.getSize() - 1
<< " elements to keep in my send list to processor " << p
<< " (communication tag : "
<< Tag::genTag(p, 0, RECEIVE_LIST_TAG) << ")");
comm.receive(keep_element.storage(),
keep_element.getSize(),
p,
Tag::genTag(p, 0, RECEIVE_LIST_TAG));
for(UInt i = 0; i < keep_element.getSize() - 1; ++i) {
filtered_elements.push_back(unfiltered_elements(keep_element(i)));
}
}
comm.waitAll(isend_requests);
comm.freeCommunicationRequest(isend_requests);
for (UInt p=0; p < this->nb_proc; ++p) {
delete keep_element_recv[p];
}
delete [] keep_element_recv;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FilteredSynchronizer::updateElementList(Array<Element> * source_elements,
Array<Element> * destination_elements,
SynchElementFilter & filter) {
AKANTU_DEBUG_IN();
// loop over procs
for (UInt p = 0; p < this->nb_proc; ++p) {
if (p == this->rank) continue;
// access the element for this proc
const Array<Element> & unfiltered_elements = source_elements[p];
Array<Element> & filtered_elements = destination_elements[p];
// iterator to loop over all source elements
Array<Element>::const_iterator<Element> it = unfiltered_elements.begin();
Array<Element>::const_iterator<Element> end = unfiltered_elements.end();
// if filter accepts this element, push it into the destination elements
for (; it != end; ++it) {
const Element & element = *it;
if (filter(element)) {
filtered_elements.push_back(element);
}
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/synchronizer/filtered_synchronizer.hh b/src/synchronizer/filtered_synchronizer.hh
index c508fb3b4..992a1dc10 100644
--- a/src/synchronizer/filtered_synchronizer.hh
+++ b/src/synchronizer/filtered_synchronizer.hh
@@ -1,100 +1,101 @@
/**
* @file filtered_synchronizer.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Mathilde Radiguet <mathilde.radiguet@epfl.ch>
*
- * @date creation: Wed Sep 18 2013
- * @date last modification: Fri Sep 27 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief synchronizer that filters elements from another synchronizer
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_FILTERED_SYNCHRONIZER_HH__
#define __AKANTU_FILTERED_SYNCHRONIZER_HH__
/* -------------------------------------------------------------------------- */
#include "distributed_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class SynchElementFilter {
public:
virtual bool operator()(const Element &) = 0;
};
/* -------------------------------------------------------------------------- */
class FilteredSynchronizer : public DistributedSynchronizer {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
FilteredSynchronizer(Mesh & mesh,
SynchronizerID id = "filtered_synchronizer",
MemoryID memory_id = 0);
virtual ~FilteredSynchronizer() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get another synchronizer and filter its elements using a functor
static FilteredSynchronizer *
createFilteredSynchronizer(const DistributedSynchronizer & d_synchronizer,
SynchElementFilter & filter);
protected:
/// set up the synchronizer
void setupSynchronizer(const DistributedSynchronizer & d_synchronizer,
SynchElementFilter & filter);
/// push source elements into destination elements through the filter
void updateElementList(Array<Element> * source_elements,
Array<Element> * destination_elements,
SynchElementFilter & filter);
protected:
/// Define the receive list tag
enum CommTags {
RECEIVE_LIST_TAG = 0
};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
__END_AKANTU__
#endif /* __AKANTU_FILTERED_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/grid_synchronizer.cc b/src/synchronizer/grid_synchronizer.cc
index 9c804c4f5..c523714bd 100644
--- a/src/synchronizer/grid_synchronizer.cc
+++ b/src/synchronizer/grid_synchronizer.cc
@@ -1,549 +1,551 @@
/**
* @file grid_synchronizer.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Oct 03 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief implementation of the grid synchronizer
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "grid_synchronizer.hh"
#include "aka_grid_dynamic.hh"
#include "mesh.hh"
#include "fe_engine.hh"
#include "static_communicator.hh"
#include "mesh_io.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
GridSynchronizer::GridSynchronizer(Mesh & mesh,
const ID & id,
MemoryID memory_id,
const bool register_to_event_manager) :
DistributedSynchronizer(mesh, id, memory_id, register_to_event_manager) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class E>
GridSynchronizer * GridSynchronizer::createGridSynchronizer(Mesh & mesh,
const SpatialGrid<E> & grid,
SynchronizerID id,
SynchronizerRegistry * synchronizer_registry,
const std::set<SynchronizationTag> & tags_to_register,
MemoryID memory_id,
const bool register_to_event_manager) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
GridSynchronizer & communicator = *(new GridSynchronizer(mesh, id, memory_id,
register_to_event_manager));
if(nb_proc == 1) return &communicator;
UInt spatial_dimension = mesh.getSpatialDimension();
Real * bounding_boxes = new Real[2 * spatial_dimension * nb_proc];
Real * my_bounding_box = bounding_boxes + 2 * spatial_dimension * my_rank;
// mesh.getLocalLowerBounds(my_bounding_box);
// mesh.getLocalUpperBounds(my_bounding_box + spatial_dimension);
const Vector<Real> & lower = grid.getLowerBounds();
const Vector<Real> & upper = grid.getUpperBounds();
const Vector<Real> & spacing = grid.getSpacing();
for (UInt i = 0; i < spatial_dimension; ++i) {
my_bounding_box[i ] = lower(i) - spacing(i);
my_bounding_box[spatial_dimension + i] = upper(i) + spacing(i);
}
AKANTU_DEBUG_INFO("Exchange of bounding box to detect the overlapping regions.");
comm.allGather(bounding_boxes, spatial_dimension * 2);
bool * intersects_proc = new bool[nb_proc];
std::fill_n(intersects_proc, nb_proc, true);
Int * first_cells = new Int[3 * nb_proc];
Int * last_cells = new Int[3 * nb_proc];
std::fill_n(first_cells, 3 * nb_proc, 0);
std::fill_n(first_cells, 3 * nb_proc, 0);
ElementTypeMapArray<UInt> ** element_per_proc = new ElementTypeMapArray<UInt>* [nb_proc];
for (UInt p = 0; p < nb_proc; ++p) element_per_proc[p] = NULL;
// check the overlapping between my box and the one from other processors
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank) continue;
Real * proc_bounding_box = bounding_boxes + 2 * spatial_dimension * p;
bool intersects = false;
Int * first_cell_p = first_cells + p * spatial_dimension;
Int * last_cell_p = last_cells + p * spatial_dimension;
for (UInt s = 0; s < spatial_dimension; ++s) {
// check overlapping of grid
intersects = Math::intersects(my_bounding_box[s],
my_bounding_box[spatial_dimension + s],
proc_bounding_box[s],
proc_bounding_box[spatial_dimension + s]);
intersects_proc[p] &= intersects;
if(intersects) {
AKANTU_DEBUG_INFO("I intersects with processor " << p << " in direction " << s);
// is point 1 of proc p in the dimension s in the range ?
bool point1 = Math::is_in_range(proc_bounding_box[s],
my_bounding_box[s],
my_bounding_box[s+spatial_dimension]);
// is point 2 of proc p in the dimension s in the range ?
bool point2 = Math::is_in_range(proc_bounding_box[s+spatial_dimension],
my_bounding_box[s],
my_bounding_box[s+spatial_dimension]);
Real start = 0.;
Real end = 0.;
if(point1 && !point2) {
/* |-----------| my_bounding_box(i)
* |-----------| proc_bounding_box(i)
* 1 2
*/
start = proc_bounding_box[s];
end = my_bounding_box[s+spatial_dimension];
AKANTU_DEBUG_INFO("Intersection scheme 1 in direction " << s << " with processor " << p << " [" << start << ", " << end <<"]");
} else if(point1 && point2) {
/* |-----------------| my_bounding_box(i)
* |-----------| proc_bounding_box(i)
* 1 2
*/
start = proc_bounding_box[s];
end = proc_bounding_box[s+spatial_dimension];
AKANTU_DEBUG_INFO("Intersection scheme 2 in direction " << s << " with processor " << p << " [" << start << ", " << end << "]");
} else if(!point1 && point2) {
/* |-----------| my_bounding_box(i)
* |-----------| proc_bounding_box(i)
* 1 2
*/
start = my_bounding_box[s];
end = proc_bounding_box[s+spatial_dimension];
AKANTU_DEBUG_INFO("Intersection scheme 3 in direction " << s << " with processor " << p << " [" << start << ", " << end <<"]");
} else {
/* |-----------| my_bounding_box(i)
* |-----------------| proc_bounding_box(i)
* 1 2
*/
start = my_bounding_box[s];
end = my_bounding_box[s+spatial_dimension];
AKANTU_DEBUG_INFO("Intersection scheme 4 in direction " << s << " with processor " << p << " [" << start << ", " << end <<"]");
}
first_cell_p[s] = grid.getCellID(start, s);
last_cell_p [s] = grid.getCellID(end, s);
}
}
//create the list of cells in the overlapping
typedef typename SpatialGrid<E>::CellID CellID;
std::vector<CellID> * cell_ids = new std::vector<CellID>;
if(intersects_proc[p]) {
AKANTU_DEBUG_INFO("I intersects with processor " << p);
CellID cell_id(spatial_dimension);
// for (UInt i = 0; i < spatial_dimension; ++i) {
// if(first_cell_p[i] != 0) --first_cell_p[i];
// if(last_cell_p[i] != 0) ++last_cell_p[i];
// }
for (Int fd = first_cell_p[0]; fd <= last_cell_p[0]; ++fd) {
cell_id.setID(0, fd);
if(spatial_dimension == 1) {
cell_ids->push_back(cell_id);
}
else {
for (Int sd = first_cell_p[1]; sd <= last_cell_p[1] ; ++sd) {
cell_id.setID(1, sd);
if(spatial_dimension == 2) {
cell_ids->push_back(cell_id);
} else {
for (Int ld = first_cell_p[2]; ld <= last_cell_p[2] ; ++ld) {
cell_id.setID(2, ld);
cell_ids->push_back(cell_id);
}
}
}
}
}
// get the list of elements in the cells of the overlapping
typename std::vector<CellID>::iterator cur_cell_id = cell_ids->begin();
typename std::vector<CellID>::iterator last_cell_id = cell_ids->end();
std::set<Element> * to_send = new std::set<Element>();
for (; cur_cell_id != last_cell_id; ++cur_cell_id) {
typename SpatialGrid<E>::Cell::const_iterator cur_elem = grid.beginCell(*cur_cell_id);
typename SpatialGrid<E>::Cell::const_iterator last_elem = grid.endCell(*cur_cell_id);
for (; cur_elem != last_elem; ++cur_elem) {
to_send->insert(*cur_elem);
}
}
AKANTU_DEBUG_INFO("I have prepared " << to_send->size() << " elements to send to processor " << p);
std::stringstream sstr; sstr << "element_per_proc_" << p;
element_per_proc[p] = new ElementTypeMapArray<UInt>(sstr.str(), id);
ElementTypeMapArray<UInt> & elempproc = *(element_per_proc[p]);
typename std::set<Element>::iterator elem = to_send->begin();
typename std::set<Element>::iterator last_elem = to_send->end();
for (; elem != last_elem; ++elem) {
ElementType type = elem->type;
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
// /!\ this part must be slow due to the access in the ElementTypeMapArray<UInt>
if(!elempproc.exists(type, _not_ghost))
elempproc.alloc(0, nb_nodes_per_element, type, _not_ghost);
UInt global_connect[nb_nodes_per_element];
UInt * local_connect = mesh.getConnectivity(type).storage() + elem->element * nb_nodes_per_element;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
global_connect[i] = mesh.getNodeGlobalId(local_connect[i]);
AKANTU_DEBUG_ASSERT(global_connect[i] < mesh.getNbGlobalNodes(),
"This global node send in the connectivity does not seem correct "
<< global_connect[i] << " corresponding to "
<< local_connect[i] << " from element " << elem->element);
}
elempproc(type).push_back(global_connect);
communicator.send_element[p].push_back(*elem);
}
delete to_send;
}
delete cell_ids;
}
delete [] first_cells;
delete [] last_cells;
delete [] bounding_boxes;
AKANTU_DEBUG_INFO("I have finished to compute intersection,"
<< " no it's time to communicate with my neighbors");
/**
* Sending loop, sends the connectivity asynchronously to all concerned proc
*/
std::vector<CommunicationRequest *> isend_requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank) continue;
if(intersects_proc[p]) {
ElementTypeMapArray<UInt> & elempproc = *(element_per_proc[p]);
ElementTypeMapArray<UInt>::type_iterator it_type = elempproc.firstType(_all_dimensions, _not_ghost);
ElementTypeMapArray<UInt>::type_iterator last_type = elempproc.lastType (_all_dimensions, _not_ghost);
UInt count = 0;
for (; it_type != last_type; ++it_type) {
Array<UInt> & conn = elempproc(*it_type, _not_ghost);
UInt info[2];
info[0] = (UInt) *it_type;
info[1] = conn.getSize() * conn.getNbComponent();
AKANTU_DEBUG_INFO("I have " << conn.getSize() << " elements of type " << *it_type
<< " to send to processor " << p
<< " (communication tag : " << Tag::genTag(my_rank, count, DATA_TAG) << ")");
isend_requests.push_back(comm.asyncSend(info, 2, p, Tag::genTag(my_rank, count, SIZE_TAG)));
if(info[1] != 0)
isend_requests.push_back(comm.asyncSend<UInt>(conn.storage(),
info[1],
p, Tag::genTag(my_rank, count, DATA_TAG)));
++count;
}
UInt info[2];
info[0] = (UInt) _not_defined;
info[1] = 0;
isend_requests.push_back(comm.asyncSend(info, 2, p, Tag::genTag(my_rank, count, SIZE_TAG)));
}
}
/**
* Receives the connectivity and store them in the ghosts elements
*/
Array<UInt> & global_nodes_ids = const_cast<Array<UInt> &>(mesh.getGlobalNodesIds());
Array<Int> & nodes_type = const_cast<Array<Int> &>(const_cast<const Mesh &>(mesh).getNodesType());
std::vector<CommunicationRequest *> isend_nodes_requests;
UInt nb_nodes_to_recv[nb_proc];
UInt nb_total_nodes_to_recv = 0;
UInt nb_current_nodes = global_nodes_ids.getSize();
NewNodesEvent new_nodes;
NewElementsEvent new_elements;
Array<UInt> * ask_nodes_per_proc = new Array<UInt>[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
nb_nodes_to_recv[p] = 0;
if(p == my_rank) continue;
Array<UInt> & ask_nodes = ask_nodes_per_proc[p];
UInt count = 0;
if(intersects_proc[p]) {
ElementType type = _not_defined;
do {
UInt info[2] = { 0 };
comm.receive(info, 2, p, Tag::genTag(p, count, SIZE_TAG));
type = (ElementType) info[0];
if(type != _not_defined) {
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);;
UInt nb_element = info[1] / nb_nodes_per_element;
Array<UInt> tmp_conn(nb_element, nb_nodes_per_element);
tmp_conn.clear();
if(info[1] != 0)
comm.receive<UInt>(tmp_conn.storage(), info[1], p, Tag::genTag(p, count, DATA_TAG));
AKANTU_DEBUG_INFO("I will receive " << nb_element << " elements of type " << ElementType(info[0])
<< " from processor " << p
<< " (communication tag : " << Tag::genTag(p, count, DATA_TAG) << ")");
Array<UInt> & ghost_connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(type, _ghost));
UInt nb_ghost_element = ghost_connectivity.getSize();
Element element(type, 0, _ghost);
UInt conn[nb_nodes_per_element];
for (UInt el = 0; el < nb_element; ++el) {
UInt nb_node_to_ask_for_elem = 0;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt gn = tmp_conn(el, n);
UInt ln = global_nodes_ids.find(gn);
AKANTU_DEBUG_ASSERT(gn < mesh.getNbGlobalNodes(), "This global node seems not correct " << gn << " from element " << el << " node " << n);
if(ln == UInt(-1)) {
global_nodes_ids.push_back(gn);
nodes_type.push_back(-3); // pure ghost node
ln = nb_current_nodes;
new_nodes.getList().push_back(ln);
++nb_current_nodes;
ask_nodes.push_back(gn);
++nb_node_to_ask_for_elem;
}
conn[n] = ln;
}
// all the nodes are already known locally, the element should already exists
UInt c = UInt(-1);
if(nb_node_to_ask_for_elem == 0) {
c = ghost_connectivity.find(conn);
element.element = c;
}
if(c == UInt(-1)) {
element.element = nb_ghost_element;
++nb_ghost_element;
ghost_connectivity.push_back(conn);
new_elements.getList().push_back(element);
}
communicator.recv_element[p].push_back(element);
}
}
count++;
} while(type != _not_defined);
AKANTU_DEBUG_INFO("I have " << ask_nodes.getSize()
<< " missing nodes for elements coming from processor " << p
<< " (communication tag : " << Tag::genTag(my_rank, 0, ASK_NODES_TAG) << ")");
ask_nodes.push_back(UInt(-1));
isend_nodes_requests.push_back(comm.asyncSend(ask_nodes.storage(), ask_nodes.getSize(),
p, Tag::genTag(my_rank, 0, ASK_NODES_TAG)));
nb_nodes_to_recv[p] = ask_nodes.getSize() - 1;
nb_total_nodes_to_recv += nb_nodes_to_recv[p];
}
}
comm.waitAll(isend_requests);
comm.freeCommunicationRequest(isend_requests);
for (UInt p = 0; p < nb_proc; ++p) {
if(element_per_proc[p]) delete element_per_proc[p];
}
delete [] element_per_proc;
/**
* Sends requested nodes to proc
*/
Array<Real> & nodes = const_cast<Array<Real> &>(mesh.getNodes());
UInt nb_nodes = nodes.getSize();
std::vector<CommunicationRequest *> isend_coordinates_requests;
Array<Real> * nodes_to_send_per_proc = new Array<Real>[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank || !intersects_proc[p]) continue;
Array<UInt> asked_nodes;
CommunicationStatus status;
AKANTU_DEBUG_INFO("Waiting list of nodes to send to processor " << p
<< "(communication tag : " << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
comm.probe<UInt>(p, Tag::genTag(p, 0, ASK_NODES_TAG), status);
UInt nb_nodes_to_send = status.getSize();
asked_nodes.resize(nb_nodes_to_send);
AKANTU_DEBUG_INFO("I have " << nb_nodes_to_send - 1
<< " nodes to send to processor " << p
<< " (communication tag : " << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
AKANTU_DEBUG_INFO("Getting list of nodes to send to processor " << p
<< " (communication tag : " << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
comm.receive(asked_nodes.storage(), nb_nodes_to_send, p, Tag::genTag(p, 0, ASK_NODES_TAG));
nb_nodes_to_send--;
asked_nodes.resize(nb_nodes_to_send);
Array<Real> & nodes_to_send = nodes_to_send_per_proc[p];
nodes_to_send.extendComponentsInterlaced(spatial_dimension, 1);
for (UInt n = 0; n < nb_nodes_to_send; ++n) {
UInt ln = global_nodes_ids.find(asked_nodes(n));
AKANTU_DEBUG_ASSERT(ln != UInt(-1), "The node [" << asked_nodes(n) << "] requested by proc " << p << " was not found locally!");
nodes_to_send.push_back(nodes.storage() + ln * spatial_dimension);
}
if(nb_nodes_to_send != 0) {
AKANTU_DEBUG_INFO("Sending the " << nb_nodes_to_send << " nodes to processor " << p
<< " (communication tag : " << Tag::genTag(p, 0, SEND_NODES_TAG) << ")");
isend_coordinates_requests.push_back(comm.asyncSend(nodes_to_send.storage(), nb_nodes_to_send * spatial_dimension, p, Tag::genTag(my_rank, 0, SEND_NODES_TAG)));
}
#if not defined (AKANTU_NDEBUG)
else {
AKANTU_DEBUG_INFO("No nodes to send to processor " << p);
}
#endif
}
comm.waitAll(isend_nodes_requests);
comm.freeCommunicationRequest(isend_nodes_requests);
delete [] ask_nodes_per_proc;
nodes.resize(nb_total_nodes_to_recv + nb_nodes);
for (UInt p = 0; p < nb_proc; ++p) {
if((p != my_rank) && (nb_nodes_to_recv[p] > 0)) {
AKANTU_DEBUG_INFO("Receiving the " << nb_nodes_to_recv[p] << " nodes from processor " << p
<< " (communication tag : " << Tag::genTag(p, 0, SEND_NODES_TAG) << ")");
comm.receive(nodes.storage() + nb_nodes * spatial_dimension,
nb_nodes_to_recv[p] * spatial_dimension,
p, Tag::genTag(p, 0, SEND_NODES_TAG));
nb_nodes += nb_nodes_to_recv[p];
}
#if not defined (AKANTU_NDEBUG)
else {
if(p != my_rank) {
AKANTU_DEBUG_INFO("No nodes to receive from processor " << p);
}
}
#endif
}
comm.waitAll(isend_coordinates_requests);
comm.freeCommunicationRequest(isend_coordinates_requests);
delete [] nodes_to_send_per_proc;
// Register the tags if any
if(synchronizer_registry) {
std::set<SynchronizationTag>::const_iterator it = tags_to_register.begin();
std::set<SynchronizationTag>::const_iterator end = tags_to_register.end();
for (; it != end; ++it) {
synchronizer_registry->registerSynchronizer(communicator, *it);
}
}
mesh.sendEvent(new_nodes);
mesh.sendEvent(new_elements);
delete [] intersects_proc;
AKANTU_DEBUG_OUT();
return &communicator;
}
/* -------------------------------------------------------------------------- */
template GridSynchronizer *
GridSynchronizer::createGridSynchronizer<IntegrationPoint>(Mesh & mesh,
const SpatialGrid<IntegrationPoint> & grid,
SynchronizerID id,
SynchronizerRegistry * synchronizer_registry,
const std::set<SynchronizationTag> & tags_to_register,
MemoryID memory_id,
const bool register_to_event_manager);
template GridSynchronizer *
GridSynchronizer::createGridSynchronizer<Element>(Mesh & mesh,
const SpatialGrid<Element> & grid,
SynchronizerID id,
SynchronizerRegistry * synchronizer_registry,
const std::set<SynchronizationTag> & tags_to_register,
MemoryID memory_id,
const bool register_to_event_manager);
__END_AKANTU__
diff --git a/src/synchronizer/grid_synchronizer.hh b/src/synchronizer/grid_synchronizer.hh
index 22331a268..11e1bba58 100644
--- a/src/synchronizer/grid_synchronizer.hh
+++ b/src/synchronizer/grid_synchronizer.hh
@@ -1,101 +1,102 @@
/**
* @file grid_synchronizer.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Oct 03 2011
- * @date last modification: Thu Feb 21 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
- * @brief synchronizer based in RegularGrid
+ * @brief Synchronizer based on spatial grid
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "distributed_synchronizer.hh"
#include "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_GRID_SYNCHRONIZER_HH__
#define __AKANTU_GRID_SYNCHRONIZER_HH__
__BEGIN_AKANTU__
class Mesh;
template<class T>
class SpatialGrid;
class GridSynchronizer : public DistributedSynchronizer {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
protected:
GridSynchronizer(Mesh & mesh, const ID & id = "grid_synchronizer", MemoryID memory_id = 0,
const bool register_to_event_manager = true);
public:
virtual ~GridSynchronizer() { };
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/**
*Create the Grid Synchronizer:
*Compute intersection and send info to neighbours that will be stored in ghosts elements
*/
template <class E>
static GridSynchronizer *
createGridSynchronizer(Mesh & mesh,
const SpatialGrid<E> & grid,
SynchronizerID id = "grid_synchronizer",
SynchronizerRegistry * synch_registry = NULL,
const std::set<SynchronizationTag> & tags_to_register = std::set<SynchronizationTag>(),
MemoryID memory_id = 0, const bool register_to_event_manager = true);
protected:
/// Define the tags that will be used in the send and receive instructions
enum CommTags {
SIZE_TAG = 0,
DATA_TAG = 1,
ASK_NODES_TAG = 2,
SEND_NODES_TAG = 3
};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
__END_AKANTU__
#endif /* __AKANTU_GRID_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/mpi_type_wrapper.hh b/src/synchronizer/mpi_type_wrapper.hh
index d633f76e7..45c0bdd02 100644
--- a/src/synchronizer/mpi_type_wrapper.hh
+++ b/src/synchronizer/mpi_type_wrapper.hh
@@ -1,79 +1,80 @@
/**
* @file mpi_type_wrapper.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Oct 29 2013
- * @date last modification: Tue Oct 29 2013
+ * @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 (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <mpi.h>
/* -------------------------------------------------------------------------- */
#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) {
}
template<typename T>
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);
}
inline MPI_Comm getMPICommunicator() const {
return communicator;
}
static MPI_Op getMPISynchronizerOperation(const SynchronizerOperation & op) {
return synchronizer_operation_to_mpi_op[op];
}
private:
StaticCommunicatorMPI & static_comm;
MPI_Comm communicator;
static MPI_Op synchronizer_operation_to_mpi_op[_so_null + 1];
};
__END_AKANTU__
#endif /* __AKANTU_MPI_TYPE_WRAPPER_HH__ */
diff --git a/src/synchronizer/pbc_synchronizer.cc b/src/synchronizer/pbc_synchronizer.cc
index e7c37f828..b80b27b7e 100644
--- a/src/synchronizer/pbc_synchronizer.cc
+++ b/src/synchronizer/pbc_synchronizer.cc
@@ -1,92 +1,93 @@
/**
* @file pbc_synchronizer.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Mon Jun 20 2011
- * @date last modification: Tue Nov 06 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief implementation of the synchronizer for the pbc conditions
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "pbc_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
PBCSynchronizer::PBCSynchronizer(std::map<UInt,UInt> & pairs,
SynchronizerID id,
MemoryID memory_id):
Synchronizer(id,memory_id),pbc_pair(pairs){
}
/* -------------------------------------------------------------------------- */
void PBCSynchronizer::asynchronousSynchronize(DataAccessor & data_accessor,
SynchronizationTag tag){
if (size_buffer.find(tag) == size_buffer.end())
computeBufferSize(data_accessor, tag);
buffer.resize(size_buffer[tag]);
for (std::map<UInt,UInt>::iterator it = pbc_pair.begin();
it != pbc_pair.end();
++it) {
UInt node_master = it->second;
UInt node_slave = it->first;
AKANTU_DEBUG_INFO("packing node " << node_master);
data_accessor.packData(buffer, node_master, tag);
AKANTU_DEBUG_INFO("unpacking node " << node_slave);
data_accessor.unpackData(buffer, node_slave, tag);
}
}
/* -------------------------------------------------------------------------- */
void PBCSynchronizer::waitEndSynchronize(__attribute__((unused)) DataAccessor & data_accessor,
__attribute__((unused)) SynchronizationTag tag){
}
/* -------------------------------------------------------------------------- */
void PBCSynchronizer::computeBufferSize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
UInt size = 0;
for (std::map<UInt,UInt>::iterator it = pbc_pair.begin();
it != pbc_pair.end();++it) {
size += data_accessor.getNbDataToPack(tag);
}
size_buffer[tag] = size;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/synchronizer/pbc_synchronizer.hh b/src/synchronizer/pbc_synchronizer.hh
index e152f0f43..08abe2a63 100644
--- a/src/synchronizer/pbc_synchronizer.hh
+++ b/src/synchronizer/pbc_synchronizer.hh
@@ -1,107 +1,108 @@
/**
* @file pbc_synchronizer.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Dofs Synchronizer for periodic boundary condition
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PBC_SYNCHRONIZER_HH__
#define __AKANTU_PBC_SYNCHRONIZER_HH__
/* -------------------------------------------------------------------------- */
#include "synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class PBCSynchronizer : public Synchronizer {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PBCSynchronizer(std::map<UInt,UInt> & pairs,
SynchronizerID id = "pbc_synch",
MemoryID memory_id = 0);
virtual ~PBCSynchronizer(){};
public:
/* ------------------------------------------------------------------------ */
/* Inherited from Synchronizer */
/* ------------------------------------------------------------------------ */
/// asynchronous synchronization of ghosts
void asynchronousSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
/// wait end of asynchronous synchronization of ghosts
void waitEndSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
private:
/// compute buffer size for a given tag and data accessor
void computeBufferSize(DataAccessor & data_accessor, SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// pairs of nodes slave -> master node
std::map<UInt,UInt> & pbc_pair;
/// size of packing buffer for each tag
std::map<SynchronizationTag, UInt> size_buffer;
/// buffer to pack and unpack the data
CommunicationBuffer buffer;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "pbc_synchronizer_inline_impl.cc"
// /// standard output stream operator
// inline std::ostream & operator <<(std::ostream & stream, const PBCSynchronizer & _this)
// {
// _this.printself(stream);
// return stream;
// }
__END_AKANTU__
#endif /* __AKANTU_PBC_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/real_static_communicator.hh b/src/synchronizer/real_static_communicator.hh
index aed480b2d..d703386e4 100644
--- a/src/synchronizer/real_static_communicator.hh
+++ b/src/synchronizer/real_static_communicator.hh
@@ -1,108 +1,109 @@
/**
* @file real_static_communicator.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Apr 14 2011
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Mon Jun 14 2010
+ * @date last modification: Wed Jan 13 2016
*
* @brief empty class just for inheritance
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_REAL_STATIC_COMMUNICATOR_HH__
#define __AKANTU_REAL_STATIC_COMMUNICATOR_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class CommunicationRequest {
public:
CommunicationRequest(UInt source, UInt dest);
virtual ~CommunicationRequest();
virtual void printself(std::ostream & stream, int indent = 0) const;
AKANTU_GET_MACRO(Source, source, UInt);
AKANTU_GET_MACRO(Destination, destination, UInt);
private:
UInt source;
UInt destination;
UInt id;
static UInt counter;
};
/* -------------------------------------------------------------------------- */
class CommunicationStatus {
public:
CommunicationStatus() : source(0), size(0), tag(0) {};
AKANTU_GET_MACRO(Source, source, Int);
AKANTU_GET_MACRO(Size, size, UInt);
AKANTU_GET_MACRO(Tag, tag, Int);
AKANTU_SET_MACRO(Source, source, Int);
AKANTU_SET_MACRO(Size, size, UInt);
AKANTU_SET_MACRO(Tag, tag, Int);
private:
Int source;
UInt size;
Int tag;
};
/* -------------------------------------------------------------------------- */
/// Datatype to pack pairs for MPI_{MIN,MAX}LOC
template<typename T1, typename T2>
struct SCMinMaxLoc {
T1 min_max;
T2 loc;
};
/* -------------------------------------------------------------------------- */
class StaticCommunicator;
/* -------------------------------------------------------------------------- */
class RealStaticCommunicator {
public:
RealStaticCommunicator(__attribute__ ((unused)) int & argc,
__attribute__ ((unused)) char ** & argv) {
prank = -1;
psize = -1;
};
virtual ~RealStaticCommunicator() { };
friend class StaticCommunicator;
protected:
Int prank;
Int psize;
};
__END_AKANTU__
#endif /* __AKANTU_REAL_STATIC_COMMUNICATOR_HH__ */
diff --git a/src/synchronizer/static_communicator.cc b/src/synchronizer/static_communicator.cc
index f6e3c2e09..cd0858d0b 100644
--- a/src/synchronizer/static_communicator.cc
+++ b/src/synchronizer/static_communicator.cc
@@ -1,115 +1,116 @@
/**
* @file static_communicator.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Sep 01 2010
- * @date last modification: Mon Jul 21 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 13 2016
*
* @brief implementation of the common part of the static communicator
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "static_communicator.hh"
#include "static_communicator_dummy.hh"
#ifdef AKANTU_USE_MPI
# include "static_communicator_mpi.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
bool StaticCommunicator::is_instantiated = false;
StaticCommunicator * StaticCommunicator::static_communicator = NULL;
UInt CommunicationRequest::counter = 0;
/* -------------------------------------------------------------------------- */
CommunicationRequest::CommunicationRequest(UInt source, UInt dest) :
source(source), destination(dest) {
this->id = counter++;
}
/* -------------------------------------------------------------------------- */
CommunicationRequest::~CommunicationRequest() {
}
/* -------------------------------------------------------------------------- */
void CommunicationRequest::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "CommunicationRequest [" << std::endl;
stream << space << " + id : " << id << std::endl;
stream << space << " + source : " << source << std::endl;
stream << space << " + destination : " << destination << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
StaticCommunicator::StaticCommunicator(int & argc,
char ** & argv,
CommunicatorType type) {
real_type = type;
#ifdef AKANTU_USE_MPI
if(type == _communicator_mpi) {
real_static_communicator = new StaticCommunicatorMPI(argc, argv);
} else {
#endif
real_static_communicator = new StaticCommunicatorDummy(argc, argv);
#ifdef AKANTU_USE_MPI
}
#endif
}
/* -------------------------------------------------------------------------- */
StaticCommunicator & StaticCommunicator::getStaticCommunicator(CommunicatorType type) {
AKANTU_DEBUG_IN();
if (!static_communicator) {
int nb_args = 0;
char ** null;
static_communicator = new StaticCommunicator(nb_args, null, type);
}
is_instantiated = true;
AKANTU_DEBUG_OUT();
return *static_communicator;
}
/* -------------------------------------------------------------------------- */
StaticCommunicator & StaticCommunicator::getStaticCommunicator(int & argc,
char ** & argv,
CommunicatorType type) {
if (!static_communicator)
static_communicator = new StaticCommunicator(argc, argv, type);
return getStaticCommunicator(type);
}
__END_AKANTU__
diff --git a/src/synchronizer/static_communicator.hh b/src/synchronizer/static_communicator.hh
index 3031cc36c..49e717dfa 100644
--- a/src/synchronizer/static_communicator.hh
+++ b/src/synchronizer/static_communicator.hh
@@ -1,215 +1,216 @@
/**
* @file static_communicator.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Sep 01 2010
- * @date last modification: Mon Jul 21 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 13 2016
*
* @brief Class handling the parallel communications
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STATIC_COMMUNICATOR_HH__
#define __AKANTU_STATIC_COMMUNICATOR_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_event_handler_manager.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#define AKANTU_COMMUNICATOR_LIST_0 BOOST_PP_SEQ_NIL
#include "static_communicator_dummy.hh"
#define AKANTU_COMMUNICATOR_LIST_1 \
BOOST_PP_SEQ_PUSH_BACK(AKANTU_COMMUNICATOR_LIST_0, \
(_communicator_dummy, (StaticCommunicatorDummy, BOOST_PP_NIL)))
#if defined(AKANTU_USE_MPI)
# include "static_communicator_mpi.hh"
# define AKANTU_COMMUNICATOR_LIST_ALL \
BOOST_PP_SEQ_PUSH_BACK(AKANTU_COMMUNICATOR_LIST_1, \
(_communicator_mpi, (StaticCommunicatorMPI, BOOST_PP_NIL)))
#else
# define AKANTU_COMMUNICATOR_LIST_ALL AKANTU_COMMUNICATOR_LIST_1
#endif // AKANTU_COMMUNICATOR_LIST
#include "real_static_communicator.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class RealStaticCommunicator;
struct FinalizeCommunicatorEvent {
FinalizeCommunicatorEvent(const StaticCommunicator & comm) : communicator(comm) {}
const StaticCommunicator & communicator;
};
class CommunicatorEventHandler {
public:
virtual ~CommunicatorEventHandler() {}
virtual void onCommunicatorFinalize(__attribute__((unused)) const StaticCommunicator & communicator) { }
private:
inline void sendEvent(const FinalizeCommunicatorEvent & event) {
onCommunicatorFinalize(event.communicator);
}
template<class EventHandler>
friend class EventHandlerManager;
};
class StaticCommunicator : public EventHandlerManager<CommunicatorEventHandler>{
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
protected:
StaticCommunicator(int & argc, char ** & argv,
CommunicatorType type = _communicator_mpi);
public:
virtual ~StaticCommunicator() {
FinalizeCommunicatorEvent *event = new FinalizeCommunicatorEvent(*this);
this->sendEvent(*event);
delete event;
delete real_static_communicator;
is_instantiated = false;
StaticCommunicator::static_communicator = NULL;
};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Point to Point */
/* ------------------------------------------------------------------------ */
template<typename T> inline void send(T * buffer, Int size,
Int receiver, Int tag);
template<typename T> inline void receive(T * buffer, Int size,
Int sender, Int tag);
template<typename T> inline CommunicationRequest * asyncSend(T * buffer,
Int size,
Int receiver,
Int tag);
template<typename T> inline CommunicationRequest * asyncReceive(T * buffer,
Int size,
Int sender,
Int tag);
template<typename T> inline void probe(Int sender, Int tag,
CommunicationStatus & status);
/* ------------------------------------------------------------------------ */
/* Collectives */
/* ------------------------------------------------------------------------ */
template<typename T> inline void reduce(T * values, int nb_values,
const SynchronizerOperation & op,
int root = 0);
template<typename T> inline void allReduce(T * values, int nb_values,
const SynchronizerOperation & op);
template<typename T> inline void allGather(T * values, int nb_values);
template<typename T> inline void allGatherV(T * values, int * nb_values);
template<typename T> inline void gather(T * values, int nb_values,
int root = 0);
template<typename T> inline void gatherV(T * values, int * nb_values,
int root = 0);
template<typename T> inline void broadcast(T * values, int nb_values,
int root = 0);
inline void barrier();
/* ------------------------------------------------------------------------ */
/* Request handling */
/* ------------------------------------------------------------------------ */
inline bool testRequest(CommunicationRequest * request);
inline void wait(CommunicationRequest * request);
inline void waitAll(std::vector<CommunicationRequest *> & requests);
inline void freeCommunicationRequest(CommunicationRequest * request);
inline void freeCommunicationRequest(std::vector<CommunicationRequest *> & requests);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
virtual Int getNbProc() const { return real_static_communicator->psize; };
virtual Int whoAmI() const { return real_static_communicator->prank; };
AKANTU_GET_MACRO(RealStaticCommunicator, *real_static_communicator, const RealStaticCommunicator &);
AKANTU_GET_MACRO_NOT_CONST(RealStaticCommunicator, *real_static_communicator, RealStaticCommunicator &);
template<class Comm>
Comm & getRealStaticCommunicator() { return dynamic_cast<Comm &>(*real_static_communicator); }
static StaticCommunicator & getStaticCommunicator(CommunicatorType type = _communicator_mpi);
static StaticCommunicator & getStaticCommunicator(int & argc, char ** & argv,
CommunicatorType type = _communicator_mpi);
static bool isInstantiated() { return is_instantiated; };
int getMaxTag();
int getMinTag();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
static bool is_instantiated;
static StaticCommunicator * static_communicator;
RealStaticCommunicator * real_static_communicator;
CommunicatorType real_type;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "static_communicator_inline_impl.hh"
/* -------------------------------------------------------------------------- */
/* Inline Functions ArrayBase */
/* -------------------------------------------------------------------------- */
inline std::ostream & operator<<(std::ostream & stream, const CommunicationRequest & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_STATIC_COMMUNICATOR_HH__ */
diff --git a/src/synchronizer/static_communicator_dummy.hh b/src/synchronizer/static_communicator_dummy.hh
index 37f0a492f..7820e74ca 100644
--- a/src/synchronizer/static_communicator_dummy.hh
+++ b/src/synchronizer/static_communicator_dummy.hh
@@ -1,158 +1,160 @@
/**
* @file static_communicator_dummy.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date Wed Sep 01 17:57:12 2010
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 13 2016
*
- * @brief Class handling the parallel communications
+ * @brief Dummy communicator to make everything work im sequential
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STATIC_COMMUNICATOR_DUMMY_HH__
#define __AKANTU_STATIC_COMMUNICATOR_DUMMY_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "real_static_communicator.hh"
/* -------------------------------------------------------------------------- */
#include <vector>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class StaticCommunicatorDummy : public RealStaticCommunicator {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
StaticCommunicatorDummy(__attribute__((unused)) int & argc,
__attribute__((unused)) char **& argv)
: RealStaticCommunicator(argc, argv) {
prank = 0;
psize = 1;
};
virtual ~StaticCommunicatorDummy(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
template <typename T>
void
send(__attribute__((unused)) T * buffer, __attribute__((unused)) Int size,
__attribute__((unused)) Int receiver, __attribute__((unused)) Int tag) {}
template <typename T>
void receive(__attribute__((unused)) T * buffer,
__attribute__((unused)) Int size,
__attribute__((unused)) Int sender,
__attribute__((unused)) Int tag) {}
template <typename T>
CommunicationRequest * asyncSend(__attribute__((unused)) T * buffer,
__attribute__((unused)) Int size,
__attribute__((unused)) Int receiver,
__attribute__((unused)) Int tag) {
return new CommunicationRequest(0, 0);
}
template <typename T>
CommunicationRequest * asyncReceive(__attribute__((unused)) T * buffer,
__attribute__((unused)) Int size,
__attribute__((unused)) Int sender,
__attribute__((unused)) Int tag) {
return new CommunicationRequest(0, 0);
}
template <typename T>
inline void probe(__attribute__((unused)) Int sender,
__attribute__((unused)) Int tag,
__attribute__((unused)) CommunicationStatus & status) {}
bool testRequest(__attribute__((unused)) CommunicationRequest * request) {
return true;
};
void wait(__attribute__((unused)) CommunicationRequest * request){};
void waitAll(__attribute__((unused))
std::vector<CommunicationRequest *> & requests){};
void barrier(){};
template <typename T>
void reduce(__attribute__ ((unused)) T * values,
__attribute__ ((unused)) int nb_values,
__attribute__ ((unused)) const SynchronizerOperation & op,
__attribute__ ((unused)) int root) {}
template <typename T>
void allReduce(__attribute__((unused)) T * values,
__attribute__((unused)) int nb_values,
__attribute__((unused)) const SynchronizerOperation & op) {}
template <typename T>
inline void allGather(__attribute__((unused)) T * values,
__attribute__((unused)) int nb_values) {}
template <typename T>
inline void allGatherV(__attribute__((unused)) T * values,
__attribute__((unused)) int * nb_values) {}
template <typename T>
inline void gather(__attribute__((unused)) T * values,
__attribute__((unused)) int nb_values,
__attribute__((unused)) int root = 0) {}
template <typename T>
inline void gatherV(__attribute__((unused)) T * values,
__attribute__((unused)) int * nb_values,
__attribute__((unused)) int root = 0) {}
template <typename T>
inline void broadcast(__attribute__((unused)) T * values,
__attribute__((unused)) int nb_values,
__attribute__((unused)) int root = 0) {}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
int getMaxTag() { return std::numeric_limits<int>::max(); }
int getMinTag() { return 0; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
};
__END_AKANTU__
#endif /* __AKANTU_STATIC_COMMUNICATOR_DUMMY_HH__ */
diff --git a/src/synchronizer/static_communicator_inline_impl.hh b/src/synchronizer/static_communicator_inline_impl.hh
index 63e6c1d61..d794b6801 100644
--- a/src/synchronizer/static_communicator_inline_impl.hh
+++ b/src/synchronizer/static_communicator_inline_impl.hh
@@ -1,177 +1,178 @@
/**
* @file static_communicator_inline_impl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Sep 06 2010
- * @date last modification: Mon Jun 09 2014
+ * @date last modification: Thu Dec 10 2015
*
* @brief implementation of inline functions
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
inline void StaticCommunicator::freeCommunicationRequest(CommunicationRequest * request) {
if(request) delete request;
}
/* -------------------------------------------------------------------------- */
inline void StaticCommunicator::freeCommunicationRequest(std::vector<CommunicationRequest *> & requests) {
std::vector<CommunicationRequest *>::iterator it;
for(it = requests.begin(); it != requests.end(); ++it) {
delete (*it);
}
}
#if defined(__INTEL_COMPILER)
#pragma warning ( push )
#pragma warning ( disable : 111 )
#endif //defined(__INTEL_COMPILER)
/* -------------------------------------------------------------------------- */
#define AKANTU_BOOST_REAL_COMMUNICATOR_CALL(r, call, comm_type) \
case BOOST_PP_LIST_AT(comm_type, 0): { \
BOOST_PP_LIST_AT(comm_type, 1) * comm = \
static_cast<BOOST_PP_LIST_AT(comm_type, 1) *>(real_static_communicator); \
BOOST_PP_IF(BOOST_PP_LIST_AT(call, 0), \
return comm->BOOST_PP_LIST_AT(call, 1), \
comm->BOOST_PP_LIST_AT(call, 1); break;); \
}
#define AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(call, ret) \
do { \
switch(real_type) \
{ \
BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_REAL_COMMUNICATOR_CALL, \
(ret, (call, BOST_PP_NIL)), \
AKANTU_COMMUNICATOR_LIST_ALL) \
default: \
StaticCommunicatorDummy * comm = \
static_cast<StaticCommunicatorDummy *>(real_static_communicator); \
BOOST_PP_IF(ret, return comm->call, comm->call); \
} \
} while(0)
/* -------------------------------------------------------------------------- */
template<typename T>
inline void StaticCommunicator::send(T * buffer, Int size, Int receiver, Int tag) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(send(buffer, size, receiver, tag), 0);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void StaticCommunicator::receive(T * buffer, Int size, Int sender, Int tag) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(receive(buffer, size, sender, tag), 0);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline CommunicationRequest * StaticCommunicator::asyncSend(T * buffer, Int size,
Int receiver, Int tag) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(asyncSend(buffer, size, receiver, tag), 1);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline CommunicationRequest * StaticCommunicator::asyncReceive(T * buffer, Int size,
Int sender, Int tag) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(asyncReceive(buffer, size, sender, tag), 1);
}
/* -------------------------------------------------------------------------- */
template<typename T> inline void StaticCommunicator::probe(Int sender, Int tag,
CommunicationStatus & status) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(template probe<T>(sender, tag, status), 0);
}
/* -------------------------------------------------------------------------- */
template<typename T> inline void StaticCommunicator::reduce(T * values, int nb_values,
const SynchronizerOperation & op,
int root) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(reduce(values, nb_values, op, root), 0);
}
/* -------------------------------------------------------------------------- */
template<typename T> inline void StaticCommunicator::allReduce(T * values, int nb_values,
const SynchronizerOperation & op) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(allReduce(values, nb_values, op), 0);
}
/* -------------------------------------------------------------------------- */
template<typename T> inline void StaticCommunicator::allGather(T * values, int nb_values) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(allGather(values, nb_values), 0);
}
/* -------------------------------------------------------------------------- */
template<typename T> inline void StaticCommunicator::allGatherV(T * values, int * nb_values) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(allGatherV(values, nb_values), 0);
}
/* -------------------------------------------------------------------------- */
template<typename T> inline void StaticCommunicator::gather(T * values, int nb_values, int root) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(gather(values, nb_values, root), 0);
}
/* -------------------------------------------------------------------------- */
template<typename T> inline void StaticCommunicator::gatherV(T * values, int * nb_values, int root) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(gatherV(values, nb_values, root), 0);
}
/* -------------------------------------------------------------------------- */
template<typename T> inline void StaticCommunicator::broadcast(T * values, int nb_values, int root) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(broadcast(values, nb_values, root), 0);
}
/* -------------------------------------------------------------------------- */
inline void StaticCommunicator::barrier() {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(barrier(), 0);
}
/* -------------------------------------------------------------------------- */
inline bool StaticCommunicator::testRequest(CommunicationRequest * request) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(testRequest(request), 1);
}
/* -------------------------------------------------------------------------- */
inline void StaticCommunicator::wait(CommunicationRequest * request) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(wait(request), 0);
}
/* -------------------------------------------------------------------------- */
inline void StaticCommunicator::waitAll(std::vector<CommunicationRequest *> & requests) {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(waitAll(requests), 0);
}
/* -------------------------------------------------------------------------- */
inline int StaticCommunicator::getMaxTag() {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(getMaxTag(), 1);
}
/* -------------------------------------------------------------------------- */
inline int StaticCommunicator::getMinTag() {
AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(getMinTag(), 1);
}
#if defined(__INTEL_COMPILER)
#pragma warning ( pop )
#endif //defined(__INTEL_COMPILER)
diff --git a/src/synchronizer/static_communicator_mpi.cc b/src/synchronizer/static_communicator_mpi.cc
index 99cc61b08..70c586b3c 100644
--- a/src/synchronizer/static_communicator_mpi.cc
+++ b/src/synchronizer/static_communicator_mpi.cc
@@ -1,495 +1,496 @@
/**
* @file static_communicator_mpi.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sun Sep 26 2010
- * @date last modification: Mon Jul 21 2014
+ * @date last modification: Wed Jan 13 2016
*
* @brief StaticCommunicatorMPI implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#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);
}
mpi_data = new MPITypeWrapper(*this);
mpi_data->setMPICommunicator(MPI_COMM_WORLD);
}
/* -------------------------------------------------------------------------- */
StaticCommunicatorMPI::~StaticCommunicatorMPI() { MPI_Finalize(); }
/* -------------------------------------------------------------------------- */
template <typename T>
void StaticCommunicatorMPI::send(T * buffer, Int size, Int receiver, Int tag) {
MPI_Comm communicator = mpi_data->getMPICommunicator();
MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>();
#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 <typename T>
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<T>();
#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 <typename T>
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<T>();
#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 <typename T>
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<T>();
#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 <typename T>
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<T>();
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<CommunicationRequestMPI *>(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<CommunicationRequestMPI *>(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<CommunicationRequest *> & requests) {
MPI_Status status;
std::vector<CommunicationRequest *>::iterator it;
for (it = requests.begin(); it != requests.end(); ++it) {
MPI_Request * req =
static_cast<CommunicationRequestMPI *>(*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 <typename T>
void StaticCommunicatorMPI::reduce(T * values, int nb_values,
const SynchronizerOperation & op, int root) {
MPI_Comm communicator = mpi_data->getMPICommunicator();
MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>();
#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 <typename T>
void StaticCommunicatorMPI::allReduce(T * values, int nb_values,
const SynchronizerOperation & op) {
MPI_Comm communicator = mpi_data->getMPICommunicator();
MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>();
#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 <typename T>
void StaticCommunicatorMPI::allGather(T * values, int nb_values) {
MPI_Comm communicator = mpi_data->getMPICommunicator();
MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>();
#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 <typename T>
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<T>();
#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 <typename T>
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<T>();
#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 <typename T>
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<T>();
#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 <typename T>
void StaticCommunicatorMPI::broadcast(T * values, int nb_values, int root) {
MPI_Comm communicator = mpi_data->getMPICommunicator();
MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>();
#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::getMinTag() { return 0; }
/* -------------------------------------------------------------------------- */
// template<typename T>
// MPI_Datatype StaticCommunicatorMPI::getMPIDatatype() {
// return MPI_DATATYPE_NULL;
// }
template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<char>() {
return MPI_CHAR;
}
template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<float>() {
return MPI_FLOAT;
}
template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<double>() {
return MPI_DOUBLE;
}
template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<long double>() {
return MPI_LONG_DOUBLE;
}
template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<signed int>() {
return MPI_INT;
}
template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned int>() {
return MPI_UNSIGNED;
}
template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<signed long int>() {
return MPI_LONG;
}
template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned long int>() {
return MPI_UNSIGNED_LONG;
}
template <>
MPI_Datatype MPITypeWrapper::getMPIDatatype<signed long long int>() {
return MPI_LONG_LONG;
}
template <>
MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned long long int>() {
return MPI_UNSIGNED_LONG_LONG;
}
template <>
MPI_Datatype MPITypeWrapper::getMPIDatatype<SCMinMaxLoc<double, int> >() {
return MPI_DOUBLE_INT;
}
template <>
MPI_Datatype MPITypeWrapper::getMPIDatatype<SCMinMaxLoc<float, int> >() {
return MPI_FLOAT_INT;
}
/* -------------------------------------------------------------------------- */
/* Template instantiation */
/* -------------------------------------------------------------------------- */
#define AKANTU_MPI_COMM_INSTANTIATE(T) \
template void StaticCommunicatorMPI::send<T>(T * buffer, Int size, \
Int receiver, Int tag); \
template void StaticCommunicatorMPI::receive<T>(T * buffer, Int size, \
Int sender, Int tag); \
template CommunicationRequest * StaticCommunicatorMPI::asyncSend<T>( \
T * buffer, Int size, Int receiver, Int tag); \
template CommunicationRequest * StaticCommunicatorMPI::asyncReceive<T>( \
T * buffer, Int size, Int sender, Int tag); \
template void StaticCommunicatorMPI::probe<T>(Int sender, Int tag, \
CommunicationStatus & status); \
template void StaticCommunicatorMPI::allGather<T>(T * values, \
int nb_values); \
template void StaticCommunicatorMPI::allGatherV<T>(T * values, \
int * nb_values); \
template void StaticCommunicatorMPI::gather<T>(T * values, int nb_values, \
int root); \
template void StaticCommunicatorMPI::gatherV<T>(T * values, int * nb_values, \
int root); \
template void StaticCommunicatorMPI::broadcast<T>(T * values, int nb_values, \
int root); \
template void StaticCommunicatorMPI::allReduce<T>( \
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<Real, int> >(
SCMinMaxLoc<Real, int> * buffer, Int size, Int receiver, Int tag);
template void StaticCommunicatorMPI::receive<SCMinMaxLoc<Real, int> >(
SCMinMaxLoc<Real, int> * buffer, Int size, Int sender, Int tag);
template CommunicationRequest *
StaticCommunicatorMPI::asyncSend<SCMinMaxLoc<Real, int> >(
SCMinMaxLoc<Real, int> * buffer, Int size, Int receiver, Int tag);
template CommunicationRequest *
StaticCommunicatorMPI::asyncReceive<SCMinMaxLoc<Real, int> >(
SCMinMaxLoc<Real, int> * buffer, Int size, Int sender, Int tag);
template void StaticCommunicatorMPI::probe<SCMinMaxLoc<Real, int> >(
Int sender, Int tag, CommunicationStatus & status);
template void StaticCommunicatorMPI::allGather<SCMinMaxLoc<Real, int> >(
SCMinMaxLoc<Real, int> * values, int nb_values);
template void StaticCommunicatorMPI::allGatherV<SCMinMaxLoc<Real, int> >(
SCMinMaxLoc<Real, int> * values, int * nb_values);
template void StaticCommunicatorMPI::gather<SCMinMaxLoc<Real, int> >(
SCMinMaxLoc<Real, int> * values, int nb_values, int root);
template void StaticCommunicatorMPI::gatherV<SCMinMaxLoc<Real, int> >(
SCMinMaxLoc<Real, int> * values, int * nb_values, int root);
template void StaticCommunicatorMPI::broadcast<SCMinMaxLoc<Real, int> >(
SCMinMaxLoc<Real, int> * values, int nb_values, int root);
template void StaticCommunicatorMPI::allReduce<SCMinMaxLoc<Real, int> >(
SCMinMaxLoc<Real, int> * values, int nb_values,
const SynchronizerOperation & op);
#if AKANTU_INTEGER_SIZE > 4
AKANTU_MPI_COMM_INSTANTIATE(int);
#endif
__END_AKANTU__
diff --git a/src/synchronizer/static_communicator_mpi.hh b/src/synchronizer/static_communicator_mpi.hh
index 6f93f977a..53c56c833 100644
--- a/src/synchronizer/static_communicator_mpi.hh
+++ b/src/synchronizer/static_communicator_mpi.hh
@@ -1,128 +1,129 @@
/**
* @file static_communicator_mpi.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sun Sep 05 2010
- * @date last modification: Tue Oct 29 2013
+ * @date last modification: Wed Jan 13 2016
*
* @brief class handling parallel communication trough MPI
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STATIC_COMMUNICATOR_MPI_HH__
#define __AKANTU_STATIC_COMMUNICATOR_MPI_HH__
/* -------------------------------------------------------------------------- */
#include "real_static_communicator.hh"
/* -------------------------------------------------------------------------- */
#include <vector>
__BEGIN_AKANTU__
class MPITypeWrapper;
/* -------------------------------------------------------------------------- */
class StaticCommunicatorMPI : public RealStaticCommunicator {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
StaticCommunicatorMPI(int & argc, char ** & argv);
virtual ~StaticCommunicatorMPI();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
template<typename T> void send (T * buffer, Int size, Int receiver, Int tag);
template<typename T> void receive(T * buffer, Int size, Int sender, Int tag);
template<typename T> CommunicationRequest * asyncSend (T * buffer, Int size,
Int receiver, Int tag);
template<typename T> CommunicationRequest * asyncReceive(T * buffer, Int size,
Int sender, Int tag);
template<typename T> void probe(Int sender, Int tag,
CommunicationStatus & status);
template<typename T> void allGather (T * values, int nb_values);
template<typename T> void allGatherV(T * values, int * nb_values);
template<typename T> void gather (T * values, int nb_values, int root);
template<typename T> void gatherV(T * values, int * nb_values, int root);
template<typename T> void broadcast(T * values, int nb_values, int root);
bool testRequest(CommunicationRequest * request);
void wait (CommunicationRequest * request);
void waitAll(std::vector<CommunicationRequest *> & requests);
void barrier();
template<typename T> void reduce(T * values, int nb_values,
const SynchronizerOperation & op,
int root);
template<typename T> void allReduce(T * values, int nb_values,
const SynchronizerOperation & op);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
const MPITypeWrapper & getMPITypeWrapper() const { return *mpi_data; }
MPITypeWrapper & getMPITypeWrapper() { return *mpi_data; }
int getMinTag();
int getMaxTag();
private:
void setRank(int prank) { this->prank = prank; }
void setSize(int psize) { this->psize = psize; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
friend class MPITypeWrapper;
MPITypeWrapper * mpi_data;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "static_communicator_mpi_inline_impl.hh"
__END_AKANTU__
#endif /* __AKANTU_STATIC_COMMUNICATOR_MPI_HH__ */
diff --git a/src/synchronizer/static_communicator_mpi_inline_impl.hh b/src/synchronizer/static_communicator_mpi_inline_impl.hh
index 5227f5fd6..bb8458ff5 100644
--- a/src/synchronizer/static_communicator_mpi_inline_impl.hh
+++ b/src/synchronizer/static_communicator_mpi_inline_impl.hh
@@ -1,32 +1,33 @@
/**
* @file static_communicator_mpi_inline_impl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sun Sep 05 2010
- * @date last modification: Tue Oct 29 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief implementation of the mpi communicator
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
diff --git a/src/synchronizer/synchronizer.cc b/src/synchronizer/synchronizer.cc
index bcd018f79..905681e0d 100644
--- a/src/synchronizer/synchronizer.cc
+++ b/src/synchronizer/synchronizer.cc
@@ -1,57 +1,58 @@
/**
* @file synchronizer.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Sep 01 2010
- * @date last modification: Wed Nov 13 2013
+ * @date last modification: Tue Dec 09 2014
*
* @brief implementation of the common part
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
Synchronizer::Synchronizer(SynchronizerID id, MemoryID memory_id) :
Memory(id, memory_id),
static_communicator(&StaticCommunicator::getStaticCommunicator()) {
}
/* -------------------------------------------------------------------------- */
void Synchronizer::synchronize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
asynchronousSynchronize(data_accessor,tag);
waitEndSynchronize(data_accessor,tag);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/synchronizer/synchronizer.hh b/src/synchronizer/synchronizer.hh
index 4d84441b5..769105630 100644
--- a/src/synchronizer/synchronizer.hh
+++ b/src/synchronizer/synchronizer.hh
@@ -1,173 +1,174 @@
/**
* @file synchronizer.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
- * @date creation: Wed Sep 01 2010
- * @date last modification: Tue Apr 30 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Dec 10 2015
*
- * @brief interface for communicator and pbc synchronizers
+ * @brief Common interface for synchronizers
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SYNCHRONIZER_HH__
#define __AKANTU_SYNCHRONIZER_HH__
/* -------------------------------------------------------------------------- */
#include "aka_memory.hh"
#include "data_accessor.hh"
#include "real_static_communicator.hh"
#include "static_communicator.hh"
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class Synchronizer : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Synchronizer(SynchronizerID id = "synchronizer", MemoryID memory_id = 0);
virtual ~Synchronizer(){};
virtual void printself(__attribute__((unused)) std::ostream & stream,
__attribute__((unused)) int indent = 0) const {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// synchronize ghosts
void synchronize(DataAccessor & data_accessor, SynchronizationTag tag);
/// asynchronous synchronization of ghosts
virtual void asynchronousSynchronize(DataAccessor & data_accessor,
SynchronizationTag tag) = 0;
/// wait end of asynchronous synchronization of ghosts
virtual void waitEndSynchronize(DataAccessor & data_accessor,
SynchronizationTag tag) = 0;
/// compute buffer size for a given tag and data accessor
virtual void computeBufferSize(DataAccessor & data_accessor,
SynchronizationTag tag) = 0;
/**
* tag = |__________20_________|___8____|_4_|
* | proc | num mes| ct|
*/
class Tag {
public:
Tag() : tag(0) {}
Tag(int val) : tag(val) {}
operator int() { return int(tag); } // remove the sign bit
template <typename CommTag>
static inline Tag genTag(int proc, UInt msg_count, CommTag tag) {
int max_tag = StaticCommunicator::getStaticCommunicator().getMaxTag();
int _tag = ((((proc & 0xFFFFF) << 12) + ((msg_count & 0xFF) << 4) +
((Int)tag & 0xF)));
Tag t(max_tag == 0 ? _tag : (_tag % max_tag));
return t;
}
virtual void printself(std::ostream & stream,
__attribute__((unused)) int indent = 0) const {
stream << (tag >> 12) << ":" << (tag >> 4 & 0xFF) << ":" << (tag & 0xF);
}
private:
int tag;
};
/// generate the tag from the ID
template <typename CommTag> inline Tag genTagFromID(CommTag tag) {
int max_tag = StaticCommunicator::getStaticCommunicator().getMaxTag();
int _tag = std::abs((int(hash<std::string>(this->getID())) << 4) + (tag & 0xF));
Tag t(max_tag == 0 ? _tag : (_tag % max_tag));
return t;
}
protected:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
class Communication {
public:
void resize(UInt size) {
send_buffer.resize(size);
recv_buffer.resize(size);
size_to_send.resize(size);
size_to_receive.resize(size);
}
public:
/// size of data to send to each processor
std::vector<UInt> size_to_send;
/// size of data to recv to each processor
std::vector<UInt> size_to_receive;
std::vector<CommunicationBuffer> send_buffer;
std::vector<CommunicationBuffer> recv_buffer;
std::vector<CommunicationRequest *> send_requests;
std::vector<CommunicationRequest *> recv_requests;
};
/// id of the synchronizer
SynchronizerID id;
/// message counter per tag
std::map<SynchronizationTag, UInt> tag_counter;
/// the static memory instance
StaticCommunicator * static_communicator;
};
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream,
const Synchronizer & _this) {
_this.printself(stream);
return stream;
}
inline std::ostream & operator<<(std::ostream & stream,
const Synchronizer::Tag & _this) {
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/synchronizer_registry.cc b/src/synchronizer/synchronizer_registry.cc
index e09eefcee..e8f0f3537 100644
--- a/src/synchronizer/synchronizer_registry.cc
+++ b/src/synchronizer/synchronizer_registry.cc
@@ -1,128 +1,130 @@
/**
* @file synchronizer_registry.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jun 16 2011
- * @date last modification: Tue Nov 06 2012
+ * @date last modification: Thu Oct 08 2015
*
* @brief Registry of synchronizers
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SynchronizerRegistry::SynchronizerRegistry(DataAccessor & da) :
// nb_synchronization_tags(0),
data_accessor(da) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SynchronizerRegistry::~SynchronizerRegistry() {
AKANTU_DEBUG_IN();
// for (Tag2Sync::iterator it = synchronizers.begin();
// it != synchronizers.end();
// ++it) {
// delete it->second;
// }
synchronizers.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SynchronizerRegistry::synchronize(SynchronizationTag tag) {
AKANTU_DEBUG_IN();
std::pair<Tag2Sync::iterator,Tag2Sync::iterator> range =
synchronizers.equal_range(tag);
for (Tag2Sync::iterator it = range.first; it != range.second;++it) {
(*it).second->synchronize(data_accessor,tag);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SynchronizerRegistry::asynchronousSynchronize(SynchronizationTag tag) {
AKANTU_DEBUG_IN();
std::pair<Tag2Sync::iterator,Tag2Sync::iterator> range =
synchronizers.equal_range(tag);
for (Tag2Sync::iterator it = range.first; it != range.second;++it) {
(*it).second->asynchronousSynchronize(data_accessor, tag);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SynchronizerRegistry::waitEndSynchronize(SynchronizationTag tag) {
AKANTU_DEBUG_IN();
std::pair<Tag2Sync::iterator,Tag2Sync::iterator> range =
synchronizers.equal_range(tag);
for (Tag2Sync::iterator it = range.first; it != range.second;++it) {
(*it).second->waitEndSynchronize(data_accessor,tag);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SynchronizerRegistry::registerSynchronizer(Synchronizer & synchronizer,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
synchronizers.
insert(std::pair<SynchronizationTag, Synchronizer *>(tag, &synchronizer));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SynchronizerRegistry::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "SynchronizerRegistry [" << std::endl;
Tag2Sync::const_iterator it;
for (it = synchronizers.begin(); it != synchronizers.end(); it++) {
stream << space << " + Synchronizers for tag " << (*it).first << " [" << std::endl;
(*it).second->printself(stream, indent + 1);
stream << space << " ]" << std::endl;
}
stream << space << "]" << std::endl;
}
__END_AKANTU__
diff --git a/src/synchronizer/synchronizer_registry.hh b/src/synchronizer/synchronizer_registry.hh
index 5e7e09617..fec39d058 100644
--- a/src/synchronizer/synchronizer_registry.hh
+++ b/src/synchronizer/synchronizer_registry.hh
@@ -1,115 +1,117 @@
/**
* @file synchronizer_registry.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 09 2014
*
* @brief Registry of synchronizers
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SYNCHRONIZER_REGISTRY_HH__
#define __AKANTU_SYNCHRONIZER_REGISTRY_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "data_accessor.hh"
#include "synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class SynchronizerRegistry {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SynchronizerRegistry(DataAccessor & data_accessor);
virtual ~SynchronizerRegistry();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// synchronize operation
void synchronize(SynchronizationTag tag);
/// asynchronous synchronization
void asynchronousSynchronize(SynchronizationTag tag);
/// wait end of asynchronous synchronization
void waitEndSynchronize(SynchronizationTag tag);
/// register a new synchronization
void registerSynchronizer(Synchronizer & synchronizer,SynchronizationTag tag);
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
// /// number of tags registered
// UInt nb_synchronization_tags;
typedef std::multimap<SynchronizationTag, Synchronizer *> Tag2Sync;
/// list of registered synchronization
Tag2Sync synchronizers;
/// data accessor that will permit to do the pack/unpack things
DataAccessor & data_accessor;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
// #include "synchronizer_registry_inline_impl.cc"
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const SynchronizerRegistry & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_SYNCHRONIZER_REGISTRY_HH__ */
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index ac9efb28a..30c2c2608 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,85 +1,86 @@
#===============================================================================
# @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: Thu Jul 03 2014
+# @date last modification: Wed Jan 06 2016
#
# @brief configuration for tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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")
file(GLOB_RECURSE __all_files "*.*")
set(_all_files)
foreach(_file ${__all_files})
if("${_file}" MATCHES "${PROJECT_SOURCE_DIR}/test")
file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_file})
list(APPEND _all_files ${__file})
endif()
endforeach()
file(GLOB_RECURSE __all_files "*CMakeLists.txt")
foreach(_file ${__all_files})
if("${_file}" MATCHES "${PROJECT_SOURCE_DIR}/test")
file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_file})
list(APPEND _cmakes ${__file})
endif()
endforeach()
list(APPEND AKANTU_TESTS_FILES ${_cmakes})
foreach(_file ${_all_files})
list(FIND AKANTU_TESTS_FILES ${_file} _ret)
if(_ret EQUAL -1)
list(APPEND AKANTU_TESTS_EXCLUDE_FILES /${_file})
endif()
endforeach()
set(AKANTU_TESTS_EXCLUDE_FILES ${AKANTU_TESTS_EXCLUDE_FILES} PARENT_SCOPE)
#foreach(f ${AKANTU_TESTS_EXCLUDE_FILES})
# message(${f})
#endforeach()
diff --git a/test/test_common/CMakeLists.txt b/test/test_common/CMakeLists.txt
index 37f5501a2..80a3099d0 100644
--- a/test/test_common/CMakeLists.txt
+++ b/test/test_common/CMakeLists.txt
@@ -1,41 +1,42 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Jul 30 2012
-# @date last modification: Fri Feb 21 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief configurations for common tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
add_akantu_test(test_vector "Test akantu vector")
add_mesh(test_grid_mesh circle.geo 2 1)
register_test(test_csr test_csr.cc PACKAGE core)
register_test(test_grid test_grid.cc
DEPENDS test_grid_mesh
PACKAGE core)
register_test(test_math test_math.cc PACKAGE core)
register_test(test_types test_types.cc PACKAGE core)
\ No newline at end of file
diff --git a/test/test_common/test_csr.cc b/test/test_common/test_csr.cc
index 5a48492a5..8c84bc338 100644
--- a/test/test_common/test_csr.cc
+++ b/test/test_common/test_csr.cc
@@ -1,122 +1,123 @@
/**
* @file test_csr.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jul 30 2012
- * @date last modification: Thu Dec 06 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test the CSR (compressed sparse row) data structure
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include "aka_common.hh"
#include "aka_csr.hh"
using namespace akantu;
#define N 1000
int main(int argc, char *argv[]) {
CSR<UInt> csr;
std::vector<UInt> nb_cols_per_row;
csr.resizeRows(N);
csr.clearRows();
for (UInt i = 0; i < N; ++i) {
UInt nb_cols(UInt(rand()*double(N)/(RAND_MAX+1.)));
nb_cols_per_row.push_back(nb_cols);
for (UInt j = 0; j < nb_cols; ++j) {
++csr.rowOffset(i);
}
}
csr.countToCSR();
csr.resizeCols();
csr.beginInsertions();
for (UInt i = 0; i < N; ++i) {
UInt nb_cols = nb_cols_per_row[i];
for (UInt j = 0; j < nb_cols; ++j) {
csr.insertInRow(i, nb_cols - j);
}
}
csr.endInsertions();
if(csr.getNbRows() != N) {
AKANTU_DEBUG_ERROR("The number of rows does not correspond: "
<< csr.getNbRows()
<< " != "
<< N);
}
for (UInt i = 0; i < csr.getNbRows(); ++i) {
CSR<UInt>::iterator it = csr.begin(i);
CSR<UInt>::iterator end = csr.end(i);
UInt nb_cols = nb_cols_per_row[i];
for (; it != end; ++it) {
if(nb_cols != *it) {
AKANTU_DEBUG_ERROR("The numbers stored in the row " << i << " are not correct: "
<< nb_cols
<< " != "
<< *it);
}
nb_cols--;
}
if(nb_cols != 0) {
AKANTU_DEBUG_ERROR("Not enough columns in the row " << i << ": "
<< nb_cols);
}
}
for (UInt i = 0; i < csr.getNbRows(); ++i) {
CSR<UInt>::iterator it = csr.rbegin(i);
CSR<UInt>::iterator end = csr.rend(i);
UInt nb_cols = nb_cols_per_row[i];
UInt j = nb_cols;
for (; it != end; --it) {
if((nb_cols - j + 1) != *it) {
AKANTU_DEBUG_ERROR("Reverse: The numbers stored in the row " << i << " are not correct: "
<< (nb_cols - j + 1)
<< " != "
<< *it);
}
j--;
}
if(j != 0) AKANTU_DEBUG_ERROR("Reverse: Not enough columns in the row " << i << ": "
<< j);
}
return EXIT_SUCCESS;
}
diff --git a/test/test_common/test_grid.cc b/test/test_common/test_grid.cc
index d8c06d1ca..3edc9d699 100644
--- a/test/test_common/test_grid.cc
+++ b/test/test_common/test_grid.cc
@@ -1,107 +1,108 @@
/**
* @file test_grid.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Aug 06 2012
- * @date last modification: Mon Jun 23 2014
+ * @date creation: Thu Jul 15 2010
+ * @date last modification: Thu Aug 06 2015
*
* @brief Test the grid object
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_grid_dynamic.hh"
#include "mesh.hh"
#include "mesh_io.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
const UInt spatial_dimension = 2;
akantu::initialize(argc, argv);
Mesh circle(spatial_dimension);
circle.read("circle.msh");
circle.computeBoundingBox();
const Vector<Real> & l = circle.getLocalLowerBounds();
const Vector<Real> & u = circle.getLocalUpperBounds();
Real spacing[spatial_dimension] = {0.2, 0.2};
Vector<Real> s(spacing, spatial_dimension);
Vector<Real> c = u;
c += l;
c /= 2.;
SpatialGrid<Element> grid(spatial_dimension, s, c);
Vector<Real> bary(spatial_dimension);
Element el;
el.ghost_type = _not_ghost;
Mesh::type_iterator it = circle.firstType(spatial_dimension);
Mesh::type_iterator last_type = circle.lastType (spatial_dimension);
for(; it != last_type; ++it) {
UInt nb_element = circle.getNbElement(*it);
el.type = *it;
for (UInt e = 0; e < nb_element; ++e) {
circle.getBarycenter(e, el.type, bary.storage());
el.element = e;
grid.insert(el, bary);
}
}
std::cout << grid << std::endl;
Mesh mesh(spatial_dimension, "save");
grid.saveAsMesh(mesh);
mesh.write("grid.msh");
Vector<Real> pos(spatial_dimension);
// const SpatialGrid<Element>::CellID & id = grid.getCellID(pos);
// #if !defined AKANTU_NDEBUG
// SpatialGrid<Element>::neighbor_cells_iterator nit = grid.beginNeighborCells(id);
// SpatialGrid<Element>::neighbor_cells_iterator nend = grid.endNeighborCells(id);
// for(;nit != nend; ++nit) {
// std::cout << std::endl;
// const SpatialGrid<Element>::Cell & cell = grid.getCell(*nit);
// SpatialGrid<Element>::Cell::const_iterator cit = cell.begin();
// SpatialGrid<Element>::Cell::position_iterator pit = cell.begin_pos();
// SpatialGrid<Element>::Cell::const_iterator cend = cell.end();
// for (; cit != cend; ++cit, ++pit) {
// std::cout << *cit << " " << *pit << std::endl;
// }
// }
// #endif
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_common/test_math.cc b/test/test_common/test_math.cc
index 21bc364cb..b0e724e46 100644
--- a/test/test_common/test_math.cc
+++ b/test/test_common/test_math.cc
@@ -1,71 +1,72 @@
/**
* @file test_math.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Feb 21 2014
- * @date last modification: Fri Feb 28 2014
+ * @date creation: Mon Jun 14 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test the static Math class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_math.hh"
using namespace akantu;
void checkVect(Real * x, Real * xref, UInt n) {
Real diff[n];
for(UInt i = 0; i < n; ++i) {
diff[i] = xref[i]- x[i];
}
Real norm = Math::norm(n, diff)/Math::norm(n, xref);
Real tol = 1e-12;
AKANTU_DEBUG_ASSERT(norm < tol, "x differs form xref");
}
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
Real A[3*5] = { 0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10, 11,
12, 13, 14, };
Real x1[5] = { 0, 1, 2, 3, 4 };
Real x2[3] = { 0, 1, 2 };
Real y1[3];
Math::matrix_vector(3, 5, A, x1, y1, 1.);
Real y1_ref[3] = { 90, 100, 110 };
checkVect(y1, y1_ref, 3);
Real y2[5];
Math::matVectMul<true>(3, 5, 1., A, x2, 0., y2);
Real y2_ref[5] = { 5, 14, 23, 32, 41 };
checkVect(y2, y2_ref, 5);
return 0;
}
diff --git a/test/test_common/test_types.cc b/test/test_common/test_types.cc
index 53bb2dcc5..d7216c9e4 100644
--- a/test/test_common/test_types.cc
+++ b/test/test_common/test_types.cc
@@ -1,348 +1,349 @@
/**
* @file test_types.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date Mon May 4 14:02:59 2015
+ * @date creation: Fri May 15 2015
+ * @date last modification: Sat Jul 11 2015
*
* @brief Test the types declared in aka_types.hh
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_types.hh"
#include <stdexcept>
#include <iostream>
#include <sstream>
using namespace akantu;
const Real tolerance = 1e-15;
std::string itoa(UInt a) {
std::stringstream sstr;
sstr << a;
return sstr.str();
}
UInt testcounter = 0;
struct wrap_error : std::runtime_error {
wrap_error(const std::string & msg) : std::runtime_error(msg) {}
};
struct size_error : std::runtime_error {
size_error(const std::string & msg) : std::runtime_error(msg) {}
};
struct data_error : std::runtime_error {
data_error(const std::string & msg, UInt i) : std::runtime_error(msg), index(i) {}
UInt index;
};
template<class type>
void compare_storages_with_ref(const type & a, Real * ref, UInt size, UInt line, const std::string & txt) {
std::cout << std::setw(3) << (testcounter++) << ": " << std::setw(10) << txt << " - " << a
<< " - wrapped: " << std::boolalpha << a.isWrapped() << std::endl;
if (a.size() != size)
throw size_error("the size is not correct " + itoa(a.size()) +
" instead of " + itoa(size) +
" [Test at line: " + itoa(line) + "]");
Real * a_ptr = a.storage();
for (UInt i = 0; i < a.size(); ++i) {
if (!((std::abs(a_ptr[i]) < tolerance && std::abs(ref[i]) < tolerance) ||
std::abs((a_ptr[i] - ref[i])/ a_ptr[i]) < tolerance)) {
std::stringstream txt;
txt << " std::abs(" << a_ptr[i] << " - " << ref[i]
<< " [= " << std::abs(a_ptr[i] - ref[i]) << "] ) > " << tolerance;
throw data_error("storage differs at index " + itoa(i) +
" [Test at line: " + itoa(line) + "]" + txt.str(),
i);
}
}
if (a_ptr == ref && !a.isWrapped())
throw wrap_error("the storage should be wrapped but it is not [Test at line: " + itoa(line) + "]");
if (a_ptr != ref && a.isWrapped())
throw wrap_error("the storage should not be wrapped but it is [Test at line: " + itoa(line) + "]");
}
#define COMPARE(a, aref, txt) \
compare_storages_with_ref(a, \
aref, \
sizeof(aref)/sizeof(aref[0]), \
__LINE__, \
txt)
#define COMPARE_STORAGE(a, aref, txt) \
compare_storages_with_ref(a, \
aref.storage(), \
aref.size(), \
__LINE__, \
txt)
const UInt ref_size = 10;
/* -------------------------------------------------------------------------- */
void test_constructor() {
std::cout << "=== Test constructors ===" << std::endl;
Real ref1[ref_size] = { 0. };
Real ref2[ref_size] = { 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58 };
Real ref3[ref_size] = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
std::cout << "-- Vectors: " << std::endl;
Vector<Real> v1(ref_size); COMPARE ( v1, ref1, "normal" );
Vector<Real> v2(ref_size, 1563.58); COMPARE ( v2, ref2, "defval" );
Vector<Real> v3(ref3, ref_size); COMPARE ( v3, ref3, "wrapped" );
Vector<Real> v3dcw(v3); COMPARE ( v3dcw, ref3, "wdeepcopy" );
Vector<Real> v3scw(v3, false); COMPARE ( v3scw, ref3, "wshallow" );
Vector<Real> v3dc(v3dcw); COMPARE_STORAGE( v3dc, v3dcw, "deepcopy" );
Vector<Real> v3sc(v3dcw, false); COMPARE_STORAGE( v3sc, v3dcw, "shallow" );
VectorProxy<Real> vp1(ref3, ref_size);
Vector<Real> v4(vp1); COMPARE ( v4, ref3, "proxyptr" );
VectorProxy<Real> vp2(v3dcw);
Vector<Real> v5(vp2); COMPARE_STORAGE( v5, v3dcw, "proxyvdc" );
VectorProxy<Real> vp3(v3scw);
Vector<Real> v6(vp3); COMPARE ( v6, ref3, "proxyvsc" );
/* ------------------------------------------------------------------------ */
std::cout << "-- Matrices: " << std::endl;
Matrix<Real> m1(5, 2); COMPARE ( m1, ref1 , "normal" );
Matrix<Real> m1t(2, 5); COMPARE ( m1t, ref1 , "tnormal" );
Matrix<Real> m2(5, 2, 1563.58); COMPARE ( m2, ref2 , "defval" );
Matrix<Real> m2t(2, 5, 1563.58); COMPARE ( m2t, ref2 , "tdefval" );
Matrix<Real> m3(ref3, 5, 2); COMPARE ( m3, ref3 , "wrapped" );
Matrix<Real> m3t(ref3, 2, 5); COMPARE ( m3t, ref3 , "twrapped" );
Matrix<Real> m3dcw(m3); COMPARE ( m3dcw, ref3 , "wdeepcopy" );
Matrix<Real> m3scw(m3, false); COMPARE ( m3scw, ref3 , "wshallow" );
Matrix<Real> m3dc(m3dcw); COMPARE_STORAGE( m3dc, m3dcw , "deepcopy" );
Matrix<Real> m3sc(m3dcw, false); COMPARE_STORAGE( m3sc, m3dcw , "shallow" );
Matrix<Real> m3tdcw(m3t); COMPARE (m3tdcw, ref3 , "twdeepcopy");
Matrix<Real> m3tscw(m3t, false); COMPARE (m3tscw, ref3 , "twshallow" );
Matrix<Real> m3tdc(m3tdcw); COMPARE_STORAGE( m3tdc, m3tdcw, "tdeepcopy" );
Matrix<Real> m3tsc(m3tdcw, false); COMPARE_STORAGE( m3tsc, m3tdcw, "tshallow" );
MatrixProxy<Real> mp1(ref3, 5, 2);
Matrix<Real> m4(mp1); COMPARE ( m4, ref3, "proxyptr" );
MatrixProxy<Real> mp2(m3dcw);
Matrix<Real> m5(mp2); COMPARE_STORAGE( m5, m3dcw, "proxyvdc" );
MatrixProxy<Real> mp3(m3scw);
Matrix<Real> m6(mp3); COMPARE ( m6, ref3, "proxyvsc" );
MatrixProxy<Real> mp1t(ref3, 2, 5);
Matrix<Real> m4t(mp1t); COMPARE ( m4t, ref3, "tproxyptr" );
MatrixProxy<Real> mp2t(m3tdcw);
Matrix<Real> m5t(mp2t); COMPARE_STORAGE( m5t, m3tdcw, "tproxyvdc" );
MatrixProxy<Real> mp3t(m3tscw);
Matrix<Real> m6t(mp3t); COMPARE ( m6t, ref3, "tproxyvsc" );
}
/* -------------------------------------------------------------------------- */
void test_equal_and_accessors() {
std::cout << "=== Test operator=() ===" << std::endl;
Real ref[ref_size] = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
Real mod[ref_size] = { 98.7982, 72.1227, 19.7815, 57.6722, 47.1088, 14.9865, 13.3171, 62.7973, 33.9493, 98.3052 };
std::cout << "-- Vectors: " << std::endl;
Vector<Real> v (ref, ref_size);
Vector<Real> vm(mod, ref_size);
Vector<Real> vref1(v);
Vector<Real> v1;
v1 = vref1; COMPARE_STORAGE(v1, vref1, "simple=" );
for (UInt i = 0; i < ref_size; ++i) v1 (i) = mod[i]; COMPARE (v1, mod, "s_acces" );
COMPARE_STORAGE(vref1, v, "refcheck1");
Vector<Real> v2 = vref1; COMPARE_STORAGE(v2, vref1, "construc=");
for (UInt i = 0; i < ref_size; ++i) v2 (i) = mod[i]; COMPARE (v2, mod, "c_acces" );
COMPARE_STORAGE(vref1, v, "refcheck2");
Vector<Real> vref2(vref1, false);
Vector<Real> v1w;
v1w = vref2; COMPARE_STORAGE(v1w, vref1, "w_simple=" );
for (UInt i = 0; i < ref_size; ++i) v1w(i) = mod[i]; COMPARE (v1w, mod, "ws_acces" );
try { COMPARE(vref2, ref, "refcheck3"); } catch(wrap_error &) {}
Vector<Real> v2w = vref2; COMPARE_STORAGE(v2w, vref1, "w_constru=");
for (UInt i = 0; i < ref_size; ++i) v2w(i) = mod[i]; COMPARE (v2w, mod, "wc_acces" );
try { COMPARE(vref2, ref, "refcheck4"); } catch(wrap_error &) {}
VectorProxy<Real> vp1(vref1);
Vector<Real> v3;
v3 = vp1; COMPARE_STORAGE(v3, vref1, "p_simple=" );
for (UInt i = 0; i < ref_size; ++i) v3(i) = mod[i]; COMPARE (v3, mod, "ps_acces" );
COMPARE_STORAGE(vref1, v, "refcheck5");
Vector<Real> v4 = vp1; COMPARE_STORAGE(v4, vref1, "p_constru=");
for (UInt i = 0; i < ref_size; ++i) v4(i) = mod[i];
try { COMPARE(v4, mod, "pc_acces" ); } catch (wrap_error &) {}
COMPARE(vref1, mod, "refcheck6");
try { COMPARE(vref2, mod, "refcheck7"); } catch(wrap_error &) {}
vref2 = v;
VectorProxy<Real> vp2(vref2);
Vector<Real> v3w;
v3w = vp2; COMPARE_STORAGE(v3w, vref1, "pw_simpl=");
for (UInt i = 0; i < ref_size; ++i) v3w(i) = mod[i]; COMPARE (v3w, mod, "pws_acces");
try { COMPARE(vref2, ref, "refcheck8"); } catch(wrap_error &) {}
Vector<Real> v4w = vp2; COMPARE_STORAGE( v4w, vref1, "pw_constr=");
for (UInt i = 0; i < ref_size; ++i) v4w(i) = mod[i];
try { COMPARE(v4w, mod, "pwc_acces"); } catch (wrap_error &) {}
COMPARE_STORAGE(v4w, vref2, "refcheck9");
try { COMPARE(vref2, mod, "refcheck10"); } catch(wrap_error &) {}
vref1 = v;
Real store[ref_size] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
Vector<Real> vs(store, 10);
VectorProxy<Real> vp3(vs);
vp3 = vref1;
try { COMPARE_STORAGE(vs, vref1, "vp_equal_v"); } catch(wrap_error &) {}
Vector<Real> vref3(vm);
VectorProxy<Real> vp4(vref3);
vp3 = vp4;
try { COMPARE(vs, mod, "vp_equal_vp"); } catch(wrap_error &) {}
/* ------------------------------------------------------------------------ */
std::cout << "-- Matrices: " << std::endl;
Matrix<Real> m (ref, 5, 2);
Matrix<Real> mt(ref, 2, 5);
Matrix<Real> m1 (5, 2);
Matrix<Real> m1t(2, 5);
for (UInt i = 0; i < 5; ++i) {
for (UInt j = 0; j < 2; ++j) {
m1(i, j) = ref[i + j*5];
m1t(j, i) = ref[j + i*2];
}
}
COMPARE_STORAGE( m1, m, "access" );
COMPARE_STORAGE(m1t, m, "t_access");
Matrix<Real> mm (mod, 5, 2);
Matrix<Real> mmt(mod, 2, 5);
Matrix<Real> m2(m);
Matrix<Real> m3(m);
for (UInt j = 0; j < 2; ++j) {
Vector<Real> v = m2(j);
for (UInt i = 0; i < 5; ++i)
v(i) = mm(i, j);
}
COMPARE_STORAGE(m2, mm, "slicing");
for (UInt j = 0; j < 2; ++j)
m3(j) = mm(j);
COMPARE_STORAGE(m3, mm, "slic_slic");
COMPARE(mm, mod, "refcheck");
Real mod_1[ref_size] = { 98.7982, 72.1227, 197.815, 57.6722, 47.1088, 14.9865, 13.3171, 627.973, 33.9493, 98.3052 };
Matrix<Real> m4 (mm);
m4 (2,0) = 197.815;
m4 (2,1) = 627.973;
COMPARE(m4, mod_1, "partial");
Matrix<Real> m4t(mmt);
m4t(0,1) = 197.815;
m4t(1,3) = 627.973;
COMPARE(m4t, mod_1, "t_partial");
}
/* -------------------------------------------------------------------------- */
void test_simple_operators() {
std::cout << "=== Test simple operation ===" << std::endl;
Real ref[ref_size] = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
Real mod[ref_size] = { 98.7982, 72.1227, 19.7815, 57.6722, 47.1088, 14.9865, 13.3171, 62.7973, 33.9493, 98.3052 };
Real ref_div[ref_size] = { 1.163905920192984e+00, 4.001326766509196e+00,
3.915227661071464e+00, 2.411910744798472e+00,
6.466680068348578e-01, 1.866745401547894e+00,
3.261589104432606e+00, 4.037410795054780e+00,
4.945542265554328e+00, 3.708201829329581e+00 };
Real ref_tim[ref_size] = { 4.608257412000000e+02, 1.584246923200000e+03,
1.550157669600000e+03, 9.549487955999999e+02,
2.560355252000000e+02, 7.391012610000000e+02,
1.291362291800000e+03, 1.598533687200000e+03,
1.958090547200000e+03, 1.468189848400000e+03 };
Real ref_p_mod[ref_size] = { 1.219576000000000e+02, 1.517411000000000e+02,
9.768670000000000e+01, 1.056644000000000e+02,
5.997620000000001e+01, 5.213100000000000e+01,
7.821620000000000e+01, 1.431337000000000e+02,
1.323557000000000e+02, 1.720910000000000e+02 };
Real ref_m_mod[ref_size] = { -7.563879999999999e+01, 7.495699999999999e+00,
5.812369999999999e+01, -9.680000000000000e+00,
-3.424140000000000e+01, 2.215800000000000e+01,
5.158200000000001e+01, 1.753910000000000e+01,
6.445710000000000e+01, -2.451940000000000e+01 };
std::cout << "-- Vectors: " << std::endl;
Vector<Real> v (ref, ref_size);
Vector<Real> vm(mod, ref_size);
Vector<Real> vref(v);
Vector<Real> vmod(vm);
Vector<Real> v1 = vref / 19.898; COMPARE(v1, ref_div, "v / s" );
Vector<Real> v2 = vref * 19.898; COMPARE(v2, ref_tim, "v * s" );
Vector<Real> v3 = 19.898 * vref; COMPARE(v3, ref_tim, "s * v" );
Vector<Real> v4 = vref + vmod; COMPARE(v4, ref_p_mod, "v1 + v2" );
Vector<Real> v5 = vref - vmod; COMPARE(v5, ref_m_mod, "v1 - v2" );
Vector<Real> v6 = vref; v6 *= 19.898; COMPARE(v6, ref_tim, "v *= s" );
Vector<Real> v7 = vref; v7 /= 19.898; COMPARE(v7, ref_div, "v /= s" );
Vector<Real> v8 = vref; v8 += vmod; COMPARE(v8, ref_p_mod, "v1 += v2");
Vector<Real> v9 = vref; v9 -= vmod; COMPARE(v9, ref_m_mod, "v1 -= v2");
std::cout << "-- Matrices: " << std::endl;
Matrix<Real> m (ref, 5, 2);
Matrix<Real> mm(mod, 5, 2);
Matrix<Real> mref(m);
Matrix<Real> mmod(mm);
Matrix<Real> m1 = mref / 19.898; COMPARE(m1, ref_div, "m / s" );
Matrix<Real> m2 = mref * 19.898; COMPARE(m2, ref_tim, "m * s" );
Matrix<Real> m3 = 19.898 * mref; COMPARE(m3, ref_tim, "s * m" );
Matrix<Real> m4 = mref + mmod; COMPARE(m4, ref_p_mod, "m1 + m2" );
Matrix<Real> m5 = mref - mmod; COMPARE(m5, ref_m_mod, "m1 - m2" );
Matrix<Real> m6 = mref; m6 *= 19.898; COMPARE(m6, ref_tim, "m *= s" );
Matrix<Real> m7 = mref; m7 /= 19.898; COMPARE(m7, ref_div, "m /= s" );
Matrix<Real> m8 = mref; m8 += mmod; COMPARE(m8, ref_p_mod, "m1 += m2");
Matrix<Real> m9 = mref; m9 -= mmod; COMPARE(m9, ref_m_mod, "m1 -= m2");
}
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
test_constructor();
test_equal_and_accessors();
test_simple_operators();
return 0;
}
diff --git a/test/test_common/test_vector/CMakeLists.txt b/test/test_common/test_vector/CMakeLists.txt
index 1f7ec426d..743d9f9b3 100644
--- a/test/test_common/test_vector/CMakeLists.txt
+++ b/test/test_common/test_vector/CMakeLists.txt
@@ -1,35 +1,36 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Fri Sep 03 2010
-# @date last modification: Tue Nov 06 2012
+# @date last modification: Tue Dec 02 2014
#
# @brief configuration for vector tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
register_test(test_vector test_vector.cc PACKAGE core)
register_test(test_vector_iterator test_vector_iterator.cc PACKAGE core)
register_test(test_matrix test_matrix.cc PACKAGE core)
diff --git a/test/test_common/test_vector/test_matrix.cc b/test/test_common/test_vector/test_matrix.cc
index 820ef1a62..81463c4a7 100644
--- a/test/test_common/test_vector/test_matrix.cc
+++ b/test/test_common/test_vector/test_matrix.cc
@@ -1,153 +1,154 @@
/**
* @file test_matrix.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Mar 03 2011
- * @date last modification: Tue Aug 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief tests for Matrix
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_types.hh"
#include "aka_array.hh"
#include "aka_math.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <sys/time.h>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
#define n 4
UInt nbm = 10000;
Real time;
Matrix<Real> eig_test(3, 3);
eig_test(0, 0) = 0; eig_test(0, 1) = 1; eig_test(0, 2) = 0;
eig_test(1, 0) = 1; eig_test(1, 1) = 0; eig_test(1, 2) = 0;
eig_test(2, 0) = 0; eig_test(2, 1) = 0; eig_test(2, 2) = 1;
Matrix<Real> eig_vects(3, 3);
Vector<Real> eigs(3);
eig_test.eig(eigs, eig_vects);
std::cout << "A: " << eig_test << std::endl;
std::cout << "eig(A): " << eigs << " " << Vector<Real>(eig_vects(0)) << " " << Vector<Real>(eig_vects(1)) << " " << Vector<Real>(eig_vects(2)) << std::endl;
Matrix<Real> check_eig_vects(3, 3);
check_eig_vects(0, 0) = 1./std::sqrt(2); check_eig_vects(0, 1) = 0; check_eig_vects(0, 2) = -1./std::sqrt(2);
check_eig_vects(1, 0) = 1./std::sqrt(2); check_eig_vects(1, 1) = 0; check_eig_vects(1, 2) = 1./std::sqrt(2);
check_eig_vects(2, 0) = 0; check_eig_vects(2, 1) = 1; check_eig_vects(2, 2) = 0;
for (UInt i = 0; i < 3; ++i) {
Vector<Real> eig_v = eig_vects(i);
Vector<Real> check_eig_v = check_eig_vects(i);
if(! check_eig_v.equal(eig_v, 1e-14)) {
AKANTU_DEBUG_ERROR("The " << i << "th eigen vector is not correct: " << eig_v << " should be " << check_eig_v);
}
}
Array<Real> A(nbm, n*n);
Array<Real> B(nbm, n*n);
Array<Real> C1(nbm, n*n);
Array<Real> C2(nbm, n*n);
Array<Real> C3(nbm, n*n);
Array<Real> C4(nbm, n*n);
for (UInt i = 0; i < n*n; ++i) {
A.storage()[i] = drand48();
B.storage()[i] = drand48();
}
for (UInt i = 1; i < nbm; ++i) {
memcpy(A.storage() + i * n * n, A.storage(), n*n*sizeof(Real));
memcpy(B.storage() + i * n * n, B.storage(), n*n*sizeof(Real));
}
struct timeval begin, end;
Array<Real>::matrix_iterator itA = A.begin(n,n);
Array<Real>::matrix_iterator itB = B.begin(n,n);
itA = A.begin(n,n);
itB = B.begin(n,n);
std::cerr << *itA << std::endl;
std::cerr << *itB << std::endl;
/* ------------------------------------------------------------------------ */
gettimeofday(&begin, NULL);
Math::matrix_matrix(n, n, n, A, B, C1);
gettimeofday(&end, NULL);
//time = (end.tv_sec * 1e3 + end.tv_usec * 1e-3) - (begin.tv_sec * 1e3 + begin.tv_usec * 1e-3);
time = (end.tv_sec * 1e6 + end.tv_usec) - (begin.tv_sec * 1e6 + begin.tv_usec);
std::cout << "matrix_matrix : " << std::fixed << time/nbm << "us" << std::endl;
/* ------------------------------------------------------------------------ */
Array<Real>::matrix_iterator itC = C2.begin(n,n);
gettimeofday(&begin, NULL);
for (UInt i = 0; i < nbm; ++i) {
Matrix<Real> & C = *itC;
C = *itA * *itB;
++itA; ++itB;++itC;
}
gettimeofday(&end, NULL);
itC = C2.begin(n,n);
std::cerr << *itC << std::endl;
time = (end.tv_sec * 1e6 + end.tv_usec) - (begin.tv_sec * 1e6 + begin.tv_usec);
std::cout << "it Mc() = it Ma() * it Mb() : " << std::fixed << time/nbm << "us" << std::endl;
/* ------------------------------------------------------------------------ */
Array<Real>::matrix_iterator muitA = A.begin(n,n);
Array<Real>::matrix_iterator muitB = B.begin(n,n);
Array<Real>::matrix_iterator muitC = C4.begin(n,n);
gettimeofday(&begin, NULL);
for (UInt i = 0; i < nbm; ++i) {
muitC->mul<false, false>(*muitA, *muitB);
++muitA; ++muitB;++muitC;
}
gettimeofday(&end, NULL);
muitC = C4.begin(n,n);
std::cerr << *muitC << std::endl;
time = (end.tv_sec * 1e6 + end.tv_usec) - (begin.tv_sec * 1e6 + begin.tv_usec);
std::cout << "it Mc.mul( it Ma(), it Mb()) : " << std::fixed << time/nbm << "us" << std::endl;
return 0;
}
diff --git a/test/test_common/test_vector/test_vector.cc b/test/test_common/test_vector/test_vector.cc
index 98e68bdf6..b10c1964d 100644
--- a/test/test_common/test_vector/test_vector.cc
+++ b/test/test_common/test_vector/test_vector.cc
@@ -1,76 +1,77 @@
/**
* @file test_vector.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Sep 03 2010
- * @date last modification: Thu Mar 27 2014
+ * @date creation: Tue Jun 29 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the vector class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <cstdlib>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_types.hh"
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
int def_value[3];
def_value[0] = 10;
def_value[1] = 20;
def_value[2] = 30;
std::cout << "Creating a vector" << std::endl;
akantu::Array<int> int_vect(10, 3, def_value, "test1");
for (unsigned int i = 5; i < int_vect.getSize(); ++i) {
for (unsigned int j = 0; j < int_vect.getNbComponent(); ++j) {
int_vect.storage()[i*int_vect.getNbComponent() + j] = def_value[j]*10;
}
}
std::cerr << int_vect;
int new_elem[3];
new_elem[0] = 1;
new_elem[1] = 2;
new_elem[2] = 3;
std::cout << "Testing push_back" << std::endl;
int_vect.push_back(new_elem);
int_vect.push_back(200);
int_vect.erase(0);
std::cerr << int_vect;
akantu::Array<int> int_vect0(0, 3, def_value, "test2");
std::cerr << int_vect0;
int_vect0.push_back(new_elem);
std::cerr << int_vect0;
return EXIT_SUCCESS;
}
diff --git a/test/test_common/test_vector/test_vector_iterator.cc b/test/test_common/test_vector/test_vector_iterator.cc
index 45aa63cef..40a26c52e 100644
--- a/test/test_common/test_vector/test_vector_iterator.cc
+++ b/test/test_common/test_vector/test_vector_iterator.cc
@@ -1,88 +1,89 @@
/**
* @file test_vector_iterator.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Jul 30 2012
- * @date last modification: Fri Mar 21 2014
+ * @date creation: Tue Jun 29 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test the iterator present in the vector class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include <algorithm>
#include <vector>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
#include "aka_types.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
#define N 10
int main(int argc, char *argv[]) {
typedef Array<double> RealArray;
std::cout << "Creating a vector of matrices (2,2)" << std::endl;
RealArray mat_vect(N, 4, 0.);
std::cout << "Iterating on a Matrix(2,2)" << std::endl;
RealArray::iterator<akantu::Matrix<Real> > itm;
itm = mat_vect.begin(2, 2);
RealArray::iterator<akantu::Matrix<Real> > endm = mat_vect.end(2, 2);
for (; itm != endm; ++itm) {
std::cout << *itm << std::endl;
}
std::cout << "Creating a vector of UInt" << std::endl;
Array<UInt> vect(N, 1, 0.);
std::cout << "Iterating on a UInt" << std::endl;
Array<UInt>::iterator<UInt> it = vect.begin();
Array<UInt>::iterator<UInt> end = vect.end();
std::vector<UInt> test_vect;
for (; it != end; ++it) {
UInt r = rand() % N;
*it = r;
test_vect.push_back(r);
std::cout << *it <<std::endl;
}
std::cout << "Sorting" << std::endl;
std::sort(vect.begin(), vect.end());
std::sort(test_vect.begin(), test_vect.end());
std::vector<UInt>::iterator itv = test_vect.begin();
for (it = vect.begin(); it != end; ++it, ++itv) {
std::cout << *it << " " << *itv << std::endl;
if(*it != *itv)
AKANTU_DEBUG_ERROR("The sort of the vector gived bad results ("<< *it << " != " << *itv << ")");
}
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/CMakeLists.txt b/test/test_contact/CMakeLists.txt
index 050465450..069458bd2 100644
--- a/test/test_contact/CMakeLists.txt
+++ b/test/test_contact/CMakeLists.txt
@@ -1,124 +1,125 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
#
-# @date creation: Tue May 13 2014
-# @date last modification: Mon Sep 15 2014
+# @date creation: Mon Nov 21 2011
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration file for contact tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(hertz_2D_mesh_test hertz_2D.geo 2 1)
register_test(test_hertz_2D
SOURCES hertz_2D.cc
DEPENDS hertz_2D_mesh_test
FILES_TO_COPY steel.dat
PACKAGE contact
)
add_mesh(hertz_3D_mesh_test hertz_3D.geo 3 1)
register_test(test_hertz_3D
SOURCES hertz_3D.cc
FILES_TO_COPY steel.dat hertz_3D.msh
PACKAGE contact
)
add_mesh(offset_1slave_mesh offset_1slave.geo 2 1)
register_test(test_offset_1slave
SOURCES offset_1slave.cc
DEPENDS offset_1slave_mesh
FILES_TO_COPY steel.dat
PACKAGE contact
)
add_mesh(offset_2slaves_mesh offset_2slaves.geo 2 1)
register_test(test_offset_2slaves
SOURCES offset_2slaves.cc
DEPENDS offset_2slaves_mesh
FILES_TO_COPY steel.dat
PACKAGE contact
)
#===============================================================================
# Alain Curnier suggested tests
add_mesh(acurnier_2D_1_mesh acurnier_2D_1.geo 2 1)
register_test(test_acurnier_2D_1
SOURCES acurnier_2D_1.cc
DEPENDS acurnier_2D_1_mesh
FILES_TO_COPY material.dat
PACKAGE contact
)
add_mesh(acurnier_2D_2_mesh acurnier_2D_2.geo 2 1)
register_test(test_acurnier_2D_2
SOURCES acurnier_2D_2.cc
DEPENDS acurnier_2D_2_mesh
FILES_TO_COPY material.dat
PACKAGE contact
)
add_mesh(acurnier_2D_3_mesh acurnier_2D_3.geo 2 1)
register_test(test_acurnier_2D_3
SOURCES acurnier_2D_3.cc
DEPENDS acurnier_2D_3_mesh
FILES_TO_COPY material.dat
PACKAGE contact
)
add_mesh(acurnier_3D_1_mesh acurnier_3D_1.geo 3 1)
register_test(test_acurnier_3D_1
SOURCES acurnier_3D_1.cc
DEPENDS acurnier_3D_1_mesh
FILES_TO_COPY material.dat
PACKAGE contact
)
add_mesh(acurnier_3D_2_mesh acurnier_3D_2.geo 3 1)
register_test(test_acurnier_3D_2
SOURCES acurnier_3D_2.cc
DEPENDS acurnier_3D_2_mesh
FILES_TO_COPY material.dat
PACKAGE contact
)
add_mesh(acurnier_3D_3_mesh acurnier_3D_3.geo 3 1)
register_test(test_acurnier_3D_3
SOURCES acurnier_3D_3.cc
DEPENDS acurnier_3D_3_mesh
FILES_TO_COPY material.dat
PACKAGE contact
)
diff --git a/test/test_contact/acurnier_2D_1.cc b/test/test_contact/acurnier_2D_1.cc
index ef41acd80..cfbaf69ef 100644
--- a/test/test_contact/acurnier_2D_1.cc
+++ b/test/test_contact/acurnier_2D_1.cc
@@ -1,107 +1,107 @@
/**
* @file acurnier_2D_1.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file implements the first simple test suggested by Alain Curnier
* for the verification of the implicit contact implementation of the Augmented
* lagrangian formulation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 2;
// type definitions
typedef SolidMechanicsModel model_type;
typedef Contact<dim, MasterAssignator,
SelectResolution<_static, _augmented_lagrangian> >
contact_type;
initialize("material.dat", argc, argv);
// create meshes
Mesh mesh(dim);
// read meshes
mesh.read("acurnier_2D_1.msh");
// create models
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
MeshDataMaterialSelector<std::string> material_selector("physical_names", model);
model.setMaterialSelector(material_selector);
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
mesh.createGroupsFromMeshData<std::string>("physical_names");
cd.addSlave(4);
cd.addArea(4, 1.0);
// add master surface to find pairs
cd.searchSurface("Contact");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Top");
// fix entire contact body
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Bottom");
Real U = 0.5;
Real Du = 0.01;
for (Real u = Du; u <= U; u += Du) {
model.applyBC(BC::Dirichlet::FixedValue(-u, _y), "Top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_generalized_newton>(cd);
}
cout<<"Force: "<< cd.getForce()<<endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/acurnier_2D_2.cc b/test/test_contact/acurnier_2D_2.cc
index 76b80abf1..9dc077c27 100644
--- a/test/test_contact/acurnier_2D_2.cc
+++ b/test/test_contact/acurnier_2D_2.cc
@@ -1,109 +1,109 @@
/**
* @file acurnier_2D_2.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file implements the first simple test suggested by Alain Curnier
* for the verification of the implicit contact implementation of the Augmented
* lagrangian formulation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 2;
// type definitions
typedef SolidMechanicsModel model_type;
typedef Contact<dim, MasterAssignator,
SelectResolution<_static, _augmented_lagrangian> >
contact_type;
initialize("material.dat", argc, argv);
// create meshes
Mesh mesh(dim);
// read meshes
mesh.read("acurnier_2D_2.msh");
// create models
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
MeshDataMaterialSelector<std::string> material_selector("physical_names", model);
model.setMaterialSelector(material_selector);
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
// model.addDumpField("element_index_by_material");
mesh.createGroupsFromMeshData<std::string>("physical_names");
cd.addSlave(4);
cd.addSlave(7);
cd.addArea(4, 1.0);
cd.addArea(7, 1.0);
// add master surface to find pairs
cd.searchSurface("Contact");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Top");
// fix entire contact body
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Bottom");
Real U = 0.5;
Real Du = 0.01;
for (Real u = Du; u <= U; u += Du) {
model.applyBC(BC::Dirichlet::FixedValue(-u, _y), "Top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_generalized_newton>(cd);
}
cout<<"Force: "<< cd.getForce()<<endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/acurnier_2D_3.cc b/test/test_contact/acurnier_2D_3.cc
index e0c25fb59..5b39fba29 100644
--- a/test/test_contact/acurnier_2D_3.cc
+++ b/test/test_contact/acurnier_2D_3.cc
@@ -1,110 +1,110 @@
/**
* @file acurnier_2D_3.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file implements the third simple test suggested by Alain Curnier
* for the verification of the implicit contact implementation of the Augmented
* lagrangian formulation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 2;
// type definitions
typedef SolidMechanicsModel model_type;
typedef Contact<dim, MasterAssignator,
SelectResolution<_static, _augmented_lagrangian> >
contact_type;
initialize("material.dat", argc, argv);
// create meshes
Mesh mesh(dim);
// read meshes
mesh.read("acurnier_2D_3.msh");
// create models
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
MeshDataMaterialSelector<std::string> material_selector("physical_names",
model);
model.setMaterialSelector(material_selector);
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
mesh.createGroupsFromMeshData<std::string>("physical_names");
cd.addSlave(4);
cd.addSlave(7);
cd.addSlave(9);
cd.addArea(4, 1.0);
cd.addArea(7, 1.0);
cd.addArea(9, 1.0);
// add master surface to find pairs
cd.searchSurface("Contact");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Top");
// fix entire contact body
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Bottom");
Real U = 0.5;
Real Du = 0.01;
for (Real u = Du; u <= U; u += Du) {
model.applyBC(BC::Dirichlet::FixedValue(-u, _y), "Top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_generalized_newton>(cd);
}
cout << "Force: " << cd.getForce() << endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/acurnier_3D_1.cc b/test/test_contact/acurnier_3D_1.cc
index 53b7edafa..e90d6745f 100644
--- a/test/test_contact/acurnier_3D_1.cc
+++ b/test/test_contact/acurnier_3D_1.cc
@@ -1,109 +1,109 @@
/**
* @file acurnier_3D_1.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file implements the fourth simple test suggested by Alain
* Curnier for the verification of the implicit contact implementation of the
* Augmented lagrangian formulation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 3;
// type definitions
typedef SolidMechanicsModel model_type;
typedef Contact<dim, MasterAssignator,
SelectResolution<_static, _augmented_lagrangian> >
contact_type;
initialize("material.dat", argc, argv);
// create meshes
Mesh mesh(dim);
// read meshes
mesh.read("acurnier_3D_1.msh");
// create models
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
MeshDataMaterialSelector<std::string> material_selector("physical_names", model);
model.setMaterialSelector(material_selector);
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
mesh.createGroupsFromMeshData<std::string>("physical_names");
cd.addSlave(4);
cd.addArea(4, 1.0);
// add master surface to find pairs
cd.searchSurface("Contact");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Top");
model.applyBC(BC::Dirichlet::FixedValue(0., _z), "Top");
// fix entire contact body
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _z), "Bottom");
Real U = 0.5;
Real Du = 0.01;
for (Real u = Du; u <= U; u += Du) {
model.applyBC(BC::Dirichlet::FixedValue(-u, _y), "Top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_generalized_newton>(cd);
}
cout<<"Force: "<< cd.getForce()<<endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/acurnier_3D_2.cc b/test/test_contact/acurnier_3D_2.cc
index 1a421ba56..7ab0a330d 100644
--- a/test/test_contact/acurnier_3D_2.cc
+++ b/test/test_contact/acurnier_3D_2.cc
@@ -1,113 +1,113 @@
/**
* @file acurnier_3D_2.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file implements the fifth simple test suggested by Alain
* Curnier for the verification of the implicit contact implementation of the
* Augmented lagrangian formulation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 3;
// type definitions
typedef SolidMechanicsModel model_type;
typedef Contact<dim, MasterAssignator,
SelectResolution<_static, _augmented_lagrangian> >
contact_type;
initialize("material.dat", argc, argv);
// create meshes
Mesh mesh(dim);
// read meshes
mesh.read("acurnier_3D_2.msh");
// create models
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
MeshDataMaterialSelector<std::string> material_selector("physical_names", model);
model.setMaterialSelector(material_selector);
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
mesh.createGroupsFromMeshData<std::string>("physical_names");
cd.addSlave(5);
cd.addSlave(6);
cd.addSlave(11);
cd.addArea(5, 1.0);
cd.addArea(6, 1.0);
cd.addArea(11, 1.0);
// add master surface to find pairs
cd.searchSurface("Contact");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Top");
model.applyBC(BC::Dirichlet::FixedValue(0., _z), "Top");
// fix entire contact body
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _z), "Bottom");
Real U = 0.5;
Real Du = 0.01;
for (Real u = Du; u <= U; u += Du) {
model.applyBC(BC::Dirichlet::FixedValue(-u, _y), "Top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_generalized_newton>(cd);
}
cout<<"Force: "<< cd.getForce()<<endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/acurnier_3D_3.cc b/test/test_contact/acurnier_3D_3.cc
index 3737b4418..458e56ea3 100644
--- a/test/test_contact/acurnier_3D_3.cc
+++ b/test/test_contact/acurnier_3D_3.cc
@@ -1,117 +1,117 @@
/**
* @file acurnier_3D_3.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file implements the sixth simple test suggested by Alain
* Curnier for the verification of the implicit contact implementation of the
* Augmented lagrangian formulation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 3;
// type definitions
typedef SolidMechanicsModel model_type;
typedef Contact<dim, MasterAssignator,
SelectResolution<_static, _augmented_lagrangian> >
contact_type;
initialize("material.dat", argc, argv);
// create meshes
Mesh mesh(dim);
// read meshes
mesh.read("acurnier_3D_3.msh");
// create models
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
MeshDataMaterialSelector<std::string> material_selector("physical_names", model);
model.setMaterialSelector(material_selector);
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
mesh.createGroupsFromMeshData<std::string>("physical_names");
cd.addSlave(4);
cd.addSlave(5);
cd.addSlave(6);
cd.addSlave(7);
cd.addSlave(20);
cd.addArea(4, 1.0);
cd.addArea(5, 1.0);
cd.addArea(6, 1.0);
cd.addArea(7, 1.0);
cd.addArea(20, 1.0);
// add master surface to find pairs
cd.searchSurface("Contact");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Top");
model.applyBC(BC::Dirichlet::FixedValue(0., _z), "Top");
// fix entire contact body
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _z), "Bottom");
Real U = 0.5;
Real Du = 0.01;
for (Real u = Du; u <= U; u += Du) {
model.applyBC(BC::Dirichlet::FixedValue(-u, _y), "Top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_generalized_newton>(cd);
}
cout<<"Force: "<< cd.getForce()<<endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/hertz_2D.cc b/test/test_contact/hertz_2D.cc
index 4b12cf992..24ecef969 100644
--- a/test/test_contact/hertz_2D.cc
+++ b/test/test_contact/hertz_2D.cc
@@ -1,172 +1,172 @@
/**
* @file hertz_2D.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Tue May 13 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file tests for the Hertz solution in 2D
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
#include "dumpable_inline_impl.hh"
using namespace akantu;
using std::cout;
using std::endl;
using std::setw;
using std::setprecision;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 2;
// type definitions
typedef Point<dim> point_type;
typedef BoundingBox<dim> bbox_type;
typedef SolidMechanicsModel model_type;
typedef ModelElement<model_type> master_type;
typedef Contact <dim, MasterAssignator, SelectResolution <_static, _augmented_lagrangian> >
contact_type;
initialize("steel.dat", argc, argv);
// create mesh
Mesh mesh(dim);
// read mesh
mesh.read("hertz_2D.msh");
// create model
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// optimal value of penalty multiplier
cd[Alpha] = 0.4;
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
// use bounding box to minimize slave-master pairs
Real r0 = 0.5;
Real r1 = 0.15;
point_type c1(-r0/2,-r1/2);
point_type c2( r0/2, r1/2);
bbox_type bb(c1, c2);
// get physical names from mesh
Array<Real> &coords = mesh.getNodes();
mesh.createGroupsFromMeshData<std::string>("physical_names");
// compute areas for slave nodes that are used for the computation of contact pressures
model.applyBC(BC::Neumann::FromHigherDim(Matrix<Real>::eye(2,1.)), "contact_surface");
// NOTE: the areas are computed by assigning a unit pressure to the contact surface,
// then the magnitude of the resulting force vector at nodes gives its associated area
Array<Real>& areas = model.getForce();
// add slave-master pairs and store slave node areas
ElementGroup &eg = mesh.getElementGroup("contact_surface");
ElementGroup &rs = mesh.getElementGroup("rigid");
for (auto nit = eg.node_begin(); nit != eg.node_end(); ++nit) {
// get point of slave node
point_type n(&coords(*nit));
// process only if within bounding box
if (bb & n) {
// loop over element types
for (ElementGroup::type_iterator tit = rs.firstType(); tit != rs.lastType(); ++tit)
// loop over elements of the rigid surface
for (ElementGroup::const_element_iterator it = rs.element_begin(*tit);
it != rs.element_end(*tit); ++it) {
// create master element
master_type m(model, _segment_2, *it);
assert(has_projection(n,m.point<2>(0),m.point<2>(1)));
// add slave-master pair
cd.addPair(*nit,m);
}
// compute and add area to slave node
Real a = 0.;
for (UInt i=0; i<dim; ++i)
a += pow(areas(*nit, i),2.);
cd.addArea(*nit, sqrt(a));
}
}
// clear force vector before the start of the simulation
areas.clear();
// output contact data info
cout<<cd;
// apply boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "rigid");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "rigid");
model.getBlockedDOFs()(7,0) = true;
Real data[3][50]; // store results for printing
Real step = 0.001; // top displacement increment
Real Delta = 0.05; // maximum imposed displacement
size_t k=0;
// loop over displacement increments
for (Real delta = step; delta <= Delta+step; delta += step) {
// apply displacement at the top
model.applyBC(BC::Dirichlet::FixedValue(-delta, _y), "top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_uzawa>(cd);
data[0][k] = delta;
data[1][k] = cd.getForce();
data[2][k] = cd.getMaxPressure();
++k;
}
// print results
size_t w = 10;
cout<<setprecision(2);
cout<<setw(w)<<"\nDisp."<<setw(w)<<"Force"<<setw(w)<<"Max pressure"<<endl;
for (int i=0; i<50; ++i)
cout<<setw(w)<<data[0][i]<<setw(w)<<data[1][i]<<setw(w)<<data[2][i]<<endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/hertz_3D.cc b/test/test_contact/hertz_3D.cc
index 4606af351..b7d129d08 100644
--- a/test/test_contact/hertz_3D.cc
+++ b/test/test_contact/hertz_3D.cc
@@ -1,170 +1,170 @@
/**
* @file hertz_3D.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Tue May 13 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file tests for the Hertz solution in 3D
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
#include "dumpable_inline_impl.hh"
using namespace akantu;
using std::cout;
using std::endl;
using std::setw;
using std::setprecision;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 3;
// type definitions
typedef Point <dim> point_type;
typedef BoundingBox <dim> bbox_type;
typedef SolidMechanicsModel model_type;
typedef Contact <dim, MasterAssignator, SelectResolution <_static, _augmented_lagrangian> >
contact_type;
initialize("steel.dat", argc, argv);
// create mesh
Mesh mesh(dim);
// read mesh
mesh.read("hertz_3D.msh");
// create model
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
// initialize material
model.initFull(opt);
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// optimal value of penalty multiplier
cd[Alpha] = 0.125;
cd[Multiplier_tol] = 1.e-2;
cd[Newton_tol] = 1.e-2;
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
// call update current position to be able to call later
// the function to get current positions
model.updateCurrentPosition();
// get physical names from Gmsh file
mesh.createGroupsFromMeshData <std::string>("physical_names");
// set-up bounding box to include slave nodes that lie inside it
Real l1 = 1.;
Real l2 = 0.2;
Real l3 = 1.;
point_type c1(-l1 / 2, -l2 / 2, -l3 / 2);
point_type c2(l1 / 2, l2 / 2, l3 / 2);
bbox_type bb(c1, c2);
// get areas for the nodes of the circle
// this is done by applying a unit pressure to the contact surface elements
model.applyBC(BC::Neumann::FromHigherDim(Matrix <Real>::eye(3, 1.)), "contact_surface");
Array <Real>& areas = model.getForce();
// loop over contact surface nodes and store node areas
ElementGroup &eg = mesh.getElementGroup("contact_surface");
Array <Real> &coords = mesh.getNodes();
cout << "- Adding areas to slave nodes. " << endl;
for (auto nit = eg.node_begin(); nit != eg.node_end(); ++nit) {
point_type p(&coords(*nit));
// ignore slave node if it doesn't lie within the bounding box
if (!(bb & p))
continue;
cd.addSlave(*nit);
// compute area contributing to the slave node
Real a = 0.;
for (UInt i = 0; i < dim; ++i)
a += pow(areas(*nit, i), 2.);
cd.addArea(*nit, sqrt(a));
}
// set force value to zero
areas.clear();
// output contact data info
cout<<cd;
// add master surface to find pairs
cd.searchSurface("rigid_surface");
// apply boundary conditions for the rigid plane
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "bottom_body");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "bottom_body");
model.applyBC(BC::Dirichlet::FixedValue(0., _z), "bottom_body");
// block z-disp in extreme points of top surface
model.getBlockedDOFs()(1, 2) = true;
model.getBlockedDOFs()(2, 2) = true;
// block x-disp in extreme points of top surface
model.getBlockedDOFs()(3, 0) = true;
model.getBlockedDOFs()(4, 0) = true;
const size_t steps = 20;
Real data[3][steps]; // store results for printing
Real step = 0.001; // top displacement increment
size_t k = 0;
for (Real delta = 0; delta <= step * steps; delta += step) {
// apply displacement to the top surface of the half-sphere
model.applyBC(BC::Dirichlet::FixedValue(-delta, _y), "top_surface");
// solve contact step, this function also dumps Paraview files
solveContactStep<_uzawa>(cd);
data[0][k] = delta;
data[1][k] = cd.getForce();
data[2][k] = cd.getMaxPressure();
++k;
}
// print results
size_t w = 14;
cout << setprecision(4);
cout << endl << setw(w) << "Disp." << setw(w) << "Force" << setw(w) << "Max pressure" << endl;
for (size_t i = 0; i < steps; ++i)
cout << setw(w) << data[0][i] << setw(w) << data[1][i] << setw(w) << data[2][i] << endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/offset_1slave.cc b/test/test_contact/offset_1slave.cc
index 09ff226a1..31add9b60 100644
--- a/test/test_contact/offset_1slave.cc
+++ b/test/test_contact/offset_1slave.cc
@@ -1,103 +1,103 @@
/**
* @file offset_1slave.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file tests the basic contact implementation using the
* generalized Newton method
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
using namespace akantu;
using std::cout;
using std::endl;
using std::setw;
using std::setprecision;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 2;
// type definitions
typedef SolidMechanicsModel model_type;
typedef Contact<dim, MasterAssignator,
SelectResolution<_static, _augmented_lagrangian> >
contact_type;
initialize("steel.dat", argc, argv);
// create meshes
Mesh mesh(dim);
// read meshes
mesh.read("offset_1slave.msh");
// create models
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
// initialize material
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
mesh.createGroupsFromMeshData<std::string>("physical_names");
cd.addSlave(4);
cd.addArea(4, 1.0);
// add master surface to find pairs
cd.searchSurface("Contact");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Top");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Bottom");
Real U = 0.5;
Real Du = 0.01;
for (Real u = Du; u <= U; u += Du) {
model.applyBC(BC::Dirichlet::FixedValue(-u, _y), "Top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_generalized_newton>(cd);
}
cout<<"Force: "<< cd.getForce()<<endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_contact/offset_2slaves.cc b/test/test_contact/offset_2slaves.cc
index 45f866efe..b3762ad92 100644
--- a/test/test_contact/offset_2slaves.cc
+++ b/test/test_contact/offset_2slaves.cc
@@ -1,103 +1,103 @@
/**
* @file offset_2slaves.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Mon Sep 15 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief This file tests the basic contact implementation using the
* generalized Newton method
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "contact_impl.hh"
using namespace akantu;
using std::cout;
using std::endl;
using std::setw;
using std::setprecision;
int main(int argc, char *argv[]) {
// set dimension
static const UInt dim = 2;
// type definitions
typedef SolidMechanicsModel model_type;
typedef Contact<dim, MasterAssignator,
SelectResolution<_static, _augmented_lagrangian> >
contact_type;
initialize("steel.dat", argc, argv);
// create meshes
Mesh mesh(dim);
// read meshes
mesh.read("offset_2slaves.msh");
// create models
model_type model(mesh);
SolidMechanicsModelOptions opt(_static);
// initialize material
// initialize material
model.initFull(opt);
model.updateCurrentPosition();
// create data structure that holds contact data
contact_type cd(argc, argv, model);
// set Paraview output resluts
model.setBaseName("contact");
model.addDumpFieldVector("displacement");
mesh.createGroupsFromMeshData<std::string>("physical_names");
cd.addSlave(4);
cd.addArea(4, 1.0);
// add master surface to find pairs
cd.searchSurface("Contact");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Top");
model.applyBC(BC::Dirichlet::FixedValue(0., _x), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Bottom");
Real U = 0.5;
Real Du = 0.01;
for (Real u = Du; u <= U; u += Du) {
model.applyBC(BC::Dirichlet::FixedValue(-u, _y), "Top");
// solve contact step (no need to call solve on the model object)
solveContactStep<_generalized_newton>(cd);
}
cout<<"Force: "<< cd.getForce()<<endl;
// finalize simulation
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_fe_engine/CMakeLists.txt b/test/test_fe_engine/CMakeLists.txt
index 220d485e9..300b19ec4 100644
--- a/test/test_fe_engine/CMakeLists.txt
+++ b/test/test_fe_engine/CMakeLists.txt
@@ -1,92 +1,93 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Fri Sep 03 2010
-# @date last modification: Fri May 30 2014
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for FEM tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
#===============================================================================
function(register_fem_test operation type)
set(_target test_${operation}${type})
register_test(${_target}
SOURCES test_${operation}.cc
FILES_TO_COPY ${type}.msh
COMPILE_OPTIONS TYPE=${type}
PACKAGE core
)
endfunction()
#===============================================================================
package_get_element_types(core _types)
foreach(_type ${_types})
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_type}.msh)
register_fem_test(fe_engine_precomputation ${_type})
register_fem_test(interpolate ${_type})
register_fem_test(gradient ${_type})
register_fem_test(integrate ${_type})
register_fem_test(inverse_map ${_type})
else()
if(NOT ${_type} STREQUAL _point_1)
message("The mesh ${_type}.msh is missing, the fe_engine test cannot be activated without it")
endif()
endif()
endforeach()
#register_test(test_interpolate_bernoulli_beam_2 test_interpolate_bernoulli_beam_2.cc)
#add_mesh(test_fem_circle_1_mesh circle.geo 2 1 OUTPUT circle1.msh)
#add_mesh(test_fem_circle_2_mesh circle.geo 2 2 OUTPUT circle2.msh)
# Tests for class MeshData
macro(register_typed_test test_name type value1 value2)
set(target test_${test_name}_${type})
register_test(${target}
SOURCES test_${test_name}.cc
COMPILE_OPTIONS "TYPE=${type};VALUE1=${value1};VALUE2=${value2}"
PACKAGE core
)
endmacro()
register_typed_test(mesh_data string \"5\" \"10\")
register_typed_test(mesh_data UInt 5 10)
add_mesh(test_boundary_msh cube.geo 3 1)
add_mesh(test_boundary_msh_physical_names cube_physical_names.geo 3 1)
register_test(test_mesh_boundary
SOURCES test_mesh_boundary.cc
DEPENDS test_boundary_msh test_boundary_msh_physical_names
PACKAGE core)
register_test(test_facet_element_mapping
SOURCES test_facet_element_mapping.cc
DEPENDS test_boundary_msh_physical_names
PACKAGE core)
diff --git a/test/test_fe_engine/test_facet_element_mapping.cc b/test/test_fe_engine/test_facet_element_mapping.cc
index 0f3fbeb4e..0dccaed58 100644
--- a/test/test_fe_engine/test_facet_element_mapping.cc
+++ b/test/test_fe_engine/test_facet_element_mapping.cc
@@ -1,120 +1,120 @@
/**
* @file test_facet_element_mapping.cc
*
* @author Dana Christen <dana.christen@gmail.com>
*
* @date creation: Fri May 03 2013
- * @date last modification: Wed May 08 2013
+ * @date last modification: Mon Jul 13 2015
*
* @brief Test of the MeshData class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include "mesh_utils.hh"
#include "aka_common.hh"
#include "aka_error.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <string>
/* -------------------------------------------------------------------------- */
using namespace akantu;
using namespace std;
int main(int argc, char *argv[]) {
// Testing the subelement-to-element mappings
UInt spatial_dimension(3);
akantu::initialize(argc, argv);
Mesh mesh(spatial_dimension, "my_mesh");
mesh.read("./cube_physical_names.msh");
typedef Array< std::vector<Element> > ElemToSubelemMapping;
typedef Array<Element> SubelemToElemMapping;
std::cout << "ELEMENT-SUBELEMENT MAPPING:" << std::endl;
for (ghost_type_t::iterator git = ghost_type_t::begin(); git != ghost_type_t::end(); ++git) {
Mesh::type_iterator tit = mesh.firstType(spatial_dimension, *git);
Mesh::type_iterator tend = mesh.lastType(spatial_dimension, *git);
std::cout << " " << "Ghost type: " << *git << std::endl;
for (;tit != tend; ++tit) {
const SubelemToElemMapping & subelement_to_element = mesh.getSubelementToElement(*tit, *git);
std::cout << " " << " " << "Element type: " << *tit << std::endl;
std::cout << " " << " " << " " << "subelement_to_element:" << std::endl;
subelement_to_element.printself(std::cout, 8);
for(UInt i(0); i < subelement_to_element.getSize(); ++i) {
std::cout << " ";
for(UInt j(0); j < mesh.getNbFacetsPerElement(*tit); ++j) {
if(subelement_to_element(i, j) != ElementNull) {
subelement_to_element(i, j).printself(std::cout);
std::cout << ", ";
} else {
std::cout << "ElementNull" << ", ";
}
}
std::cout << "for element " << i << std::endl;
}
}
tit = mesh.firstType(spatial_dimension -1, *git);
tend = mesh.lastType(spatial_dimension -1 , *git);
for (;tit != tend; ++tit) {
const ElemToSubelemMapping & element_to_subelement = mesh.getElementToSubelement(*tit, *git);
std::cout << " " << " " << "Element type: " << *tit << std::endl;
std::cout << " " << " " << " " << "element_to_subelement:" << std::endl;
element_to_subelement.printself(std::cout, 8);
for(UInt i(0); i < element_to_subelement.getSize(); ++i) {
const std::vector<Element> & vec = element_to_subelement(i);
std::cout << " " ;
std::cout << "item " << i << ": [ ";
if(vec.size() > 0) {
for(UInt j(0); j < vec.size(); ++j) {
if(vec[j] != ElementNull) {
std::cout << vec[j] << ", ";
} else {
std::cout << "ElementNull" << ", ";
}
}
} else {
std::cout << "empty, " ;
}
std::cout << "]" << ", " << std::endl;
}
std::cout << std::endl;
}
}
return 0;
}
diff --git a/test/test_fe_engine/test_fe_engine_precomputation.cc b/test/test_fe_engine/test_fe_engine_precomputation.cc
index 26728e7e2..1b84e4b20 100644
--- a/test/test_fe_engine/test_fe_engine_precomputation.cc
+++ b/test/test_fe_engine/test_fe_engine_precomputation.cc
@@ -1,63 +1,64 @@
/**
- * @file test_interpolate.cc
+ * @file test_fe_engine_precomputation.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Jun 17 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Jun 14 2010
+ * @date last modification: Mon Jul 13 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "fe_engine.hh"
#include "shape_lagrange.hh"
#include "integrator_gauss.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
debug::setDebugLevel(dblTest);
const ElementType type = TYPE;
UInt dim = ElementClass<type>::getSpatialDimension();
Mesh my_mesh(dim);
std::stringstream meshfilename; meshfilename << type << ".msh";
my_mesh.read(meshfilename.str());
FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
fem->initShapeFunctions();
std::cout << *fem << std::endl;
delete fem;
finalize();
return 0;
}
diff --git a/test/test_fe_engine/test_gradient.cc b/test/test_fe_engine/test_gradient.cc
index 15254a435..9c7fec13a 100644
--- a/test/test_fe_engine/test_gradient.cc
+++ b/test/test_fe_engine/test_gradient.cc
@@ -1,138 +1,140 @@
/**
* @file test_gradient.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Peter Spijker <peter.spijker@epfl.ch>
*
- * @date creation: Fri Jun 17 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Sep 03 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
*
* This code is computing the gradient of a linear field and check that it gives
* a constant result. It also compute the gradient the coordinates of the mesh
* and check that it gives the identity
*
*/
/* -------------------------------------------------------------------------- */
#include "fe_engine.hh"
#include "shape_lagrange.hh"
#include "integrator_gauss.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
debug::setDebugLevel(dblTest);
const ElementType type = TYPE;
UInt dim = ElementClass<type>::getSpatialDimension();
Real eps = 1e-12;
std::cout << "Epsilon : " << eps << std::endl;
Mesh my_mesh(dim);
std::stringstream meshfilename; meshfilename << type << ".msh";
my_mesh.read(meshfilename.str());
FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
fem->initShapeFunctions();
Real alpha[2][3] = {{13, 23, 31},
{11, 7, 5}};
/// create the 2 component field
const Array<Real> & position = fem->getMesh().getNodes();
Array<Real> const_val(fem->getMesh().getNbNodes(), 2, "const_val");
UInt nb_element = my_mesh.getNbElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type) * nb_element;
Array<Real> grad_on_quad(nb_quadrature_points, 2 * dim, "grad_on_quad");
for (UInt i = 0; i < const_val.getSize(); ++i) {
const_val(i, 0) = 0;
const_val(i, 1) = 0;
for (UInt d = 0; d < dim; ++d) {
const_val(i, 0) += alpha[0][d] * position(i, d);
const_val(i, 1) += alpha[1][d] * position(i, d);
}
}
/// compute the gradient
fem->gradientOnIntegrationPoints(const_val, grad_on_quad, 2, type);
std::cout << "Linear array on nodes : " << const_val << std::endl;
std::cout << "Gradient on quad : " <<grad_on_quad << std::endl;
/// check the results
Array<Real>::matrix_iterator it = grad_on_quad.begin(2,dim);
Array<Real>::matrix_iterator it_end = grad_on_quad.end(2,dim);
for (;it != it_end; ++it) {
for (UInt d = 0; d < dim; ++d) {
Matrix<Real> & grad = *it;
if(!(std::abs(grad(0, d) - alpha[0][d]) < eps) ||
!(std::abs(grad(1, d) - alpha[1][d]) < eps)) {
std::cout << "Error gradient is not correct "
<< (*it)(0, d) << " " << alpha[0][d] << " (" << std::abs((*it)(0, d) - alpha[0][d]) << ")"
<< " - "
<< (*it)(1, d) << " " << alpha[1][d] << " (" << std::abs((*it)(1, d) - alpha[1][d]) << ")"
<< " - " << d << std::endl;
std::cout << *it << std::endl;
exit(EXIT_FAILURE);
}
}
}
// compute gradient of coordinates
Array<Real> grad_coord_on_quad(nb_quadrature_points, dim * dim, "grad_coord_on_quad");
fem->gradientOnIntegrationPoints(my_mesh.getNodes(), grad_coord_on_quad, my_mesh.getSpatialDimension(), type);
std::cout << "Node positions : " << my_mesh.getNodes() << std::endl;
std::cout << "Gradient of nodes : " << grad_coord_on_quad << std::endl;
Array<Real>::matrix_iterator itp = grad_coord_on_quad.begin(dim, dim);
Array<Real>::matrix_iterator itp_end = grad_coord_on_quad.end(dim, dim);
for (;itp != itp_end; ++itp) {
for (UInt i = 0; i < dim; ++i) {
for (UInt j = 0; j < dim; ++j) {
if(!(std::abs((*itp)(i,j) - (i == j)) < eps)) {
std::cout << *itp << std::endl;
exit(EXIT_FAILURE);
}
}
}
}
delete fem;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_fe_engine/test_integrate.cc b/test/test_fe_engine/test_integrate.cc
index f8c76af0b..87bfd0847 100644
--- a/test/test_fe_engine/test_integrate.cc
+++ b/test/test_fe_engine/test_integrate.cc
@@ -1,103 +1,105 @@
/**
* @file test_integrate.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Peter Spijker <peter.spijker@epfl.ch>
*
- * @date creation: Fri Jun 17 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Sep 03 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "fe_engine.hh"
#include "shape_lagrange.hh"
#include "integrator_gauss.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
debug::setDebugLevel(dblTest);
const ElementType type = TYPE;
UInt dim = ElementClass<type>::getSpatialDimension();
Real eps = 3e-13;
std::cout << "Epsilon : " << eps << std::endl;
Mesh my_mesh(dim);
std::stringstream meshfilename; meshfilename << type << ".msh";
my_mesh.read(meshfilename.str());
FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
fem->initShapeFunctions();
UInt nb_element = my_mesh.getNbElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type) * nb_element;
Array<Real> const_val(fem->getMesh().getNbNodes(), 2, "const_val");
Array<Real> val_on_quad(nb_quadrature_points, 2 , "val_on_quad");
for (UInt i = 0; i < const_val.getSize(); ++i) {
const_val.storage()[i * 2 + 0] = 1.;
const_val.storage()[i * 2 + 1] = 2.;
}
//interpolate function on quadrature points
fem->interpolateOnIntegrationPoints(const_val, val_on_quad, 2, type);
//integrate function on elements
akantu::Array<akantu::Real> int_val_on_elem(nb_element, 2, "int_val_on_elem");
fem->integrate(val_on_quad, int_val_on_elem, 2, type);
// get global integration value
Real value[2] = {0,0};
std::cout << "Val on quads : " << val_on_quad << std::endl;
std::cout << "Integral on elements : " << int_val_on_elem << std::endl;
for (UInt i = 0; i < fem->getMesh().getNbElement(type); ++i) {
value[0] += int_val_on_elem.storage()[2*i];
value[1] += int_val_on_elem.storage()[2*i+1];
}
std::cout << "integral on the mesh of 1 is " << value[0] << " and of 2 is " << value[1] << std::endl;
delete fem;
finalize();
if(!(std::abs(value[0] - 1.) < eps && std::abs(value[1] - 2.) < eps)) {
std::cout << "|1 - " << value[0] << "| = " << std::abs(value[0] - 1.) << std::endl
<< "|2 - " << value[1] << "| = " << std::abs(value[1] - 2.) << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
diff --git a/test/test_fe_engine/test_interpolate.cc b/test/test_fe_engine/test_interpolate.cc
index 1974446e3..f1ef48cdb 100644
--- a/test/test_fe_engine/test_interpolate.cc
+++ b/test/test_fe_engine/test_interpolate.cc
@@ -1,91 +1,92 @@
/**
* @file test_interpolate.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Jun 17 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Sep 03 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "fe_engine.hh"
#include "shape_lagrange.hh"
#include "integrator_gauss.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
debug::setDebugLevel(dblTest);
const ElementType type = TYPE;
UInt dim = ElementClass<type>::getSpatialDimension();
Real eps = 3e-13;
std::cout << "Epsilon : " << eps << std::endl;
Mesh my_mesh(dim);
std::stringstream meshfilename; meshfilename << type << ".msh";
my_mesh.read(meshfilename.str());
FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
fem->initShapeFunctions();
Array<Real> const_val(fem->getMesh().getNbNodes(), 2, "const_val");
UInt nb_element = my_mesh.getNbElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type) * nb_element;
Array<Real> val_on_quad(nb_quadrature_points, 2, "val_on_quad");
for (UInt i = 0; i < const_val.getSize(); ++i) {
const_val.storage()[i * 2 + 0] = 1.;
const_val.storage()[i * 2 + 1] = 2.;
}
fem->interpolateOnIntegrationPoints(const_val, val_on_quad, 2, type);
std::cout << "Interpolation of array : " << const_val << std::endl;
std::cout << "Gives on quads : " << val_on_quad << std::endl;
// interpolate coordinates
Array<Real> coord_on_quad(nb_quadrature_points, my_mesh.getSpatialDimension(), "coord_on_quad");
fem->interpolateOnIntegrationPoints(my_mesh.getNodes(),
coord_on_quad,
my_mesh.getSpatialDimension(),
type);
std::cout << "Interpolations of node coordinates : " << my_mesh.getNodes() << std::endl;
std::cout << "Gives : " << coord_on_quad << std::endl;
delete fem;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc b/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc
index 8aed67a1f..f1f234c40 100644
--- a/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc
+++ b/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc
@@ -1,132 +1,134 @@
/**
* @file test_interpolate_bernoulli_beam_2.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date Fri Jul 15 19:41:58 2011
+ * @date creation: Fri Jul 15 2011
+ * @date last modification: Mon Jul 13 2015
*
* @brief Test of the interpolation on the type _bernoulli_beam_2
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <cstdlib>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "fe_engine.hh"
#include "integrator_gauss.hh"
#include "shape_linked.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "fe_engine_template.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]){
Mesh beams(2);
/* -------------------------------------------------------------------------- */
// Defining the mesh
Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
nodes.resize(4);
beams.addConnectivityType(_bernoulli_beam_2);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_2));
connectivity.resize(3);
for(UInt i=0; i<4; ++i) {
nodes(i,0)=(i+1)*2;
nodes(i,1)=1;
}
for(UInt i=0; i<3; ++i) {
connectivity(i,0)=i;
connectivity(i,1)=i+1;
}
akantu::MeshIOMSH mesh_io;
mesh_io.write("b_beam_2.msh", beams);
/* -------------------------------------------------------------------------- */
// Interpolation
FEEngineTemplate<IntegratorGauss,ShapeLinked> *fem = new FEEngineTemplate<IntegratorGauss,ShapeLinked>(beams,2);
fem->initShapeFunctions();
Array<Real> displ_on_nodes(4,3);
Array<Real> displ_on_quad(0,3);
for(UInt i=0; i<4; ++i) {
displ_on_nodes(i,0)=(i+1)*2; // Definition of the displacement
displ_on_nodes(i,1)=0;
displ_on_nodes(i,2)=0;
}
fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
displ_on_quad,
3,_not_ghost,
NULL, false,
0, 0, 0);
fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
displ_on_quad,
3, _not_ghost,
NULL, false,
1, 1, 1);
fem->getShapeFunctions(). interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
displ_on_quad,
3, _not_ghost,
NULL, true,
2, 2, 1);
fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
displ_on_quad,
3, _not_ghost,
NULL, false,
3, 2, 3);
fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
displ_on_quad,
3, _not_ghost,
NULL, true,
4, 3, 3);
Real * don= displ_on_nodes.storage();
Real * doq= displ_on_quad.storage();
std::ofstream my_file("out.txt");
my_file << don << std::endl;
my_file << doq << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_fe_engine/test_inverse_map.cc b/test/test_fe_engine/test_inverse_map.cc
index 2c23f2403..5aef24bce 100644
--- a/test/test_fe_engine/test_inverse_map.cc
+++ b/test/test_fe_engine/test_inverse_map.cc
@@ -1,105 +1,106 @@
/**
* @file test_inverse_map.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
- * @date creation: Fri May 25 2012
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Sep 03 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "fe_engine.hh"
#include "shape_lagrange.hh"
#include "integrator_gauss.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
debug::setDebugLevel(dblTest);
const ElementType type = TYPE;
UInt dim = ElementClass<type>::getSpatialDimension();
Mesh my_mesh(dim);
my_mesh.computeBoundingBox();
const Vector<Real> & lower = my_mesh.getLowerBounds();
const Vector<Real> & upper = my_mesh.getUpperBounds();
std::stringstream meshfilename; meshfilename << type << ".msh";
my_mesh.read(meshfilename.str());
UInt nb_elements = my_mesh.getNbElement(type);
///
FEEngineTemplate<IntegratorGauss,ShapeLagrange> *fem =
new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
fem->initShapeFunctions();
UInt nb_quad_points = fem->getNbIntegrationPoints(type);
/// get the quadrature points coordinates
Array<Real> coord_on_quad(nb_quad_points*nb_elements,
my_mesh.getSpatialDimension(),
"coord_on_quad");
fem->interpolateOnIntegrationPoints(my_mesh.getNodes(),
coord_on_quad,
my_mesh.getSpatialDimension(),
type);
/// loop over the quadrature points
Array<Real>::iterator< Vector<Real> > it = coord_on_quad.begin(dim);
Vector<Real> natural_coords(dim);
Matrix<Real> quad = GaussIntegrationElement<type>::getQuadraturePoints();
for(UInt el = 0 ; el < nb_elements ; ++el){
for(UInt q = 0 ; q < nb_quad_points ; ++q){
fem->inverseMap(*it, el, type, natural_coords);
for (UInt i = 0; i < dim; ++i) {
__attribute__ ((unused)) const Real eps = 1e-13;
AKANTU_DEBUG_ASSERT(std::abs((natural_coords(i) - quad(i,q))/(upper(i)-lower(i))) < eps,
"real coordinates inversion test failed:"
<< natural_coords(i) << " - " << quad(i, q)
<< " = " << (natural_coords(i) - quad(i, q))/(upper(i)-lower(i)));
}
++it;
}
}
std::cout << "inverse completed over " << nb_elements << " elements" << std::endl;
delete fem;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_fe_engine/test_mesh_boundary.cc b/test/test_fe_engine/test_mesh_boundary.cc
index b27645976..2a0c0d042 100644
--- a/test/test_fe_engine/test_mesh_boundary.cc
+++ b/test/test_fe_engine/test_mesh_boundary.cc
@@ -1,77 +1,78 @@
/**
* @file test_mesh_boundary.cc
*
+ * @author Dana Christen <dana.christen@gmail.com>
*
* @date creation: Fri May 03 2013
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Mon Jul 13 2015
*
- * @brief Thest the element groups
+ * @brief Thest the element groups
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <iostream>
#include <sstream>
#include "aka_common.hh"
#include "mesh.hh"
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char* argv[]) {
UInt spatialDimension(3);
akantu::initialize(argc, argv);
Mesh mesh(spatialDimension, "mesh_names");
std::cout << "Loading the mesh." << std::endl;
// mesh.read("./cube_physical_names.msh");
mesh.read("./cube_physical_names.msh");
std::stringstream sstr;
std::cout << "Examining mesh:" << std::endl;
// Inspection of the number of boundaries
__attribute__ ((unused)) UInt nb_boundaries= mesh.getNbElementGroups();
AKANTU_DEBUG_INFO(nb_boundaries << " boundaries advertised initially by Mesh.");
AKANTU_DEBUG_INFO("Building boundaries");
// Two methods: either building using data loaded from the mesh file in MeshData
// or build with automatic numbering
mesh.createGroupsFromMeshData<std::string>("physical_names");
// Second inspection of the number of boundaries (should not be 0)
nb_boundaries = mesh.getNbElementGroups();
AKANTU_DEBUG_INFO(nb_boundaries << " boundaries advertised by Mesh.");
AKANTU_DEBUG_ASSERT(nb_boundaries != 0, "No boundary detected!");
std::cout << (*dynamic_cast<GroupManager*>(&mesh)) << std::endl;
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_fe_engine/test_mesh_data.cc b/test/test_fe_engine/test_mesh_data.cc
index 169e469fb..4f0bd181f 100644
--- a/test/test_fe_engine/test_mesh_data.cc
+++ b/test/test_fe_engine/test_mesh_data.cc
@@ -1,84 +1,84 @@
/**
* @file test_mesh_data.cc
*
* @author Dana Christen <dana.christen@gmail.com>
*
* @date creation: Fri May 03 2013
- * @date last modification: Tue Jun 24 2014
+ * @date last modification: Mon Jul 13 2015
*
* @brief Test of the MeshData class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <string>
#define QUOTES(x) #x
#define ADD_QUOTES(x) QUOTES(x)
#define CAT(x,y) x ## _ ## y
#define CONCAT(x,y) CAT(x,y)
//#define TYPE std::string
//#define VALUE1 "abc"
//#define VALUE2 "qwe"
#define ELEMENT _triangle_6
#define NAME CONCAT(TYPE,data)
/* -------------------------------------------------------------------------- */
using namespace akantu;
using namespace std;
int main(int argc, char *argv[]) {
std::cout << "Testing with type " << ADD_QUOTES(TYPE)
<< " and values " << ADD_QUOTES(VALUE1) << "," << ADD_QUOTES(VALUE2) << "..." << std::endl;
MeshData mesh_data;
ElementType elem_type = ELEMENT;
const std::string name = ADD_QUOTES(NAME);
Array<TYPE> & vec = mesh_data.getElementalDataArrayAlloc<TYPE>(name, elem_type);
// XXX TO DELETE
// vec.copy(mesh_data.getElementalDataArrayAlloc<TYPE>(name, elem_type));
TYPE value[2] = {VALUE1, VALUE2 };
vec.push_back(value[0]);
vec.push_back(value[1]);
for(UInt i(0); i < 2; i++) {
AKANTU_DEBUG_ASSERT( vec(i) == value[i],
"The Array accessed through the getElementDataArray method does not contain the right value." );
}
std::cout << vec << std::endl;
std::cout << mesh_data.getTypeCode(name) << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_geometry/CMakeLists.txt b/test/test_geometry/CMakeLists.txt
index 3f385bddb..875e4b51d 100644
--- a/test/test_geometry/CMakeLists.txt
+++ b/test/test_geometry/CMakeLists.txt
@@ -1,57 +1,58 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Lucas Frerot <lucas.frerot@epfl.ch>
#
-# @date creation: Fri Feb 27 2015
-# @date last modification: Fri Feb 27 2015
+# @date creation: Fri Sep 03 2010
+# @date last modification: Thu Jan 14 2016
#
# @brief configuration for solver tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_geometry_intersection_triangle_3_mesh triangle_3.geo 2 1)
add_mesh(test_geometry_intersection_tetrahedron_4_mesh tetrahedron_4.geo 3 1)
register_test(test_geometry_predicates
SOURCES test_geometry_predicates.cc
PACKAGE CGAL
)
register_test(test_geometry_intersection
SOURCES test_geometry_intersection.cc
FILES_TO_COPY test_geometry_triangle.msh
PACKAGE CGAL
)
register_test(test_segment_intersection_triangle_3
SOURCES test_segment_intersection_triangle_3.cc
FILES_TO_COPY test_geometry_triangle.msh
PACKAGE CGAL
)
register_test(test_segment_intersection_tetrahedron_4
SOURCES test_segment_intersection_tetrahedron_4.cc
FILES_TO_COPY test_geometry_tetrahedron.msh
PACKAGE CGAL
)
diff --git a/test/test_geometry/test_geometry_intersection.cc b/test/test_geometry/test_geometry_intersection.cc
index b0232c2b8..2466b614a 100644
--- a/test/test_geometry/test_geometry_intersection.cc
+++ b/test/test_geometry/test_geometry_intersection.cc
@@ -1,127 +1,127 @@
/**
* @file test_geometry_intersection.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
- * @author Clément Roux-Langlois <clement.roux@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Fri Feb 27 2015
- * @date last modification: Thu Mar 5 2015
+ * @date last modification: Thu Jan 14 2016
*
* @brief Tests the intersection module
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_geom_factory.hh"
#include "tree_type_helper.hh"
#include "geom_helper_functions.hh"
#include "mesh_geom_common.hh"
#include <iostream>
#include <iterator>
#include <CGAL/Exact_spherical_kernel_3.h>
#include <CGAL/intersections.h>
#include <CGAL/Spherical_kernel_intersections.h>
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef Cartesian K;
typedef IntersectionTypeHelper<TreeTypeHelper<Triangle<K>, K>, K::Segment_3>::intersection_type result_type;
typedef Spherical SK;
typedef boost::variant<std::pair<SK::Circular_arc_point_3, UInt> > sk_inter_res;
/*typedef CGAL::cpp11::result_of<SK::Intersect_3(SK::Line_arc_3,
SK::Sphere_3,
std::back_insert_iterator<
std::list<sk_inter_res> >)>::type sk_res;*/
typedef std::pair<SK::Circular_arc_point_3, UInt> pair_type;
/* -------------------------------------------------------------------------- */
int main (int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblWarning);
Mesh mesh(2);
mesh.read("test_geometry_triangle.msh");
MeshGeomFactory<2, _triangle_3, Triangle<K>, K> factory(mesh);
factory.constructData();
const TreeTypeHelper<Triangle<K>, K>::tree & tree = factory.getTree();
K::Point_3 a(0., 0.25, 0.), b(1., 0.25, 0.);
K::Segment_3 line(a, b);
K::Point_3 begin(a), intermediate(0.25, 0.25, 0.), end(0.75, 0.25, 0.);
K::Segment_3 result_0(begin, intermediate), result_1(intermediate, end);
std::list<result_type> list_of_intersections;
tree.all_intersections(line, std::back_inserter(list_of_intersections));
const result_type & intersection_0 = list_of_intersections.back();
const result_type & intersection_1 = list_of_intersections.front();
if (!intersection_0 || !intersection_1)
return EXIT_FAILURE;
/// *-> first is the intersection ; *->second is the primitive id
if (const K::Segment_3 * segment = boost::get<K::Segment_3>(&(intersection_0->first))) {
if (!compareSegments(*segment, result_0)) {
return EXIT_FAILURE;
}
} else return EXIT_FAILURE;
if (const K::Segment_3 * segment = boost::get<K::Segment_3>(&(intersection_1->first))) {
if (!compareSegments(*segment, result_1)) {
return EXIT_FAILURE;
}
} else return EXIT_FAILURE;
SK::Sphere_3 sphere(SK::Point_3(0, 0, 0), 3.);
SK::Segment_3 seg(SK::Point_3(0, 0, 0), SK::Point_3(2., 2., 2.));
SK::Line_arc_3 arc(seg);
std::list<sk_inter_res> s_results;
CGAL::intersection(arc, sphere, std::back_inserter(s_results));
if (pair_type * pair = boost::get<pair_type>(&s_results.front())) {
std::cout << "xi = " << to_double(pair->first.x())
<< ", yi = " << to_double(pair->first.y()) << std::endl;
if (!comparePoints(pair->first, SK::Circular_arc_point_3(1.0, 1.0, 1.0)))
return EXIT_FAILURE;
} else return EXIT_FAILURE;
MeshGeomFactory<2, _triangle_3, Line_arc<SK>, SK> Sfactory(mesh);
Sfactory.constructData();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_geometry/test_geometry_predicates.cc b/test/test_geometry/test_geometry_predicates.cc
index 8ffab37b6..91675ae0c 100644
--- a/test/test_geometry/test_geometry_predicates.cc
+++ b/test/test_geometry/test_geometry_predicates.cc
@@ -1,88 +1,88 @@
/**
* @file test_geometry_predicates.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Thu Mar 26 2015
- * @date last modification: Thu Mar 26 2015
+ * @date creation: Fri Jan 04 2013
+ * @date last modification: Thu Jan 14 2016
*
* @brief Tests the geometry predicates
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "geom_helper_functions.hh"
#include "mesh_geom_common.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef Cartesian K;
typedef K::Point_3 Point;
typedef K::Segment_3 Segment;
int main(int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblWarning);
Point a(0, 1, 0);
Point b(0, 1, 1);
Segment seg1(a, b);
Segment seg2(b, a);
if (!compareSegments(seg1, seg2))
return EXIT_FAILURE;
// Testing sort + unique on list of segments
std::vector<std::pair<K::Segment_3, UInt> > pair_list;
pair_list.push_back(std::make_pair(seg1, 1));
pair_list.push_back(std::make_pair(seg2, 2));
segmentPairsLess sorter;
std::sort(pair_list.begin(), pair_list.end(), sorter);
std::vector<std::pair<K::Segment_3, UInt> >::iterator
it = std::unique(pair_list.begin(), pair_list.end(), compareSegmentPairs);
if (it - pair_list.begin() != 1) {
std::cout << pair_list.size() << std::endl;
return EXIT_FAILURE;
}
// Testing insertion in set
std::set<std::pair<K::Segment_3, UInt>, segmentPairsLess> pair_set;
pair_set.insert(pair_set.begin(), std::make_pair(seg1, 1));
pair_set.insert(pair_set.begin(), std::make_pair(seg2, 2));
if (pair_set.size() != 1) {
std::cout << pair_set.size() << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_geometry/test_segment_intersection_tetrahedron_4.cc b/test/test_geometry/test_segment_intersection_tetrahedron_4.cc
index fdebf0637..77343b936 100644
--- a/test/test_geometry/test_segment_intersection_tetrahedron_4.cc
+++ b/test/test_geometry/test_segment_intersection_tetrahedron_4.cc
@@ -1,148 +1,148 @@
/**
- * @file test_geometry_intersection_tetrahedron_4.cc
+ * @file test_segment_intersection_tetrahedron_4.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Thu Mar 26 2015
- * @date last modification: Thu Mar 26 2015
+ * @date creation: Fri Feb 27 2015
+ * @date last modification: Thu Jan 14 2016
*
* @brief Tests the intersection module with _tetrahedron_4 elements
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_segment_intersector.hh"
#include "mesh_geom_common.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef Cartesian K;
typedef K::Point_3 Point;
typedef K::Segment_3 Segment;
/* -------------------------------------------------------------------------- */
int main (int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblError);
Mesh mesh(3), interface_mesh(3, "interface_mesh");
mesh.read("test_geometry_tetrahedron.msh");
MeshSegmentIntersector<3, _tetrahedron_4> intersector(mesh, interface_mesh);
intersector.constructData();
// Testing a segment going through the cube
Point point(1., 1., 1.);
Segment segment(CGAL::ORIGIN, point);
intersector.computeIntersectionQuery(segment);
std::cout << "number of seg_2 : " << interface_mesh.getNbElement(_segment_2) << std::endl;
if (interface_mesh.getNbElement(_segment_2) != 2)
return EXIT_FAILURE;
Vector<Real> bary(2), bary1(2), bary2(2);
Element test;
test.type = _segment_2;
test.element = 0;
interface_mesh.getBarycenter(test, bary1);
test.element = 1;
interface_mesh.getBarycenter(test, bary2);
Real first_bary[] = {1./6., 1./6., 1./6.};
Real second_bary[] = {2./3., 2./3., 2./3.};
// We don't know the order of the elements, so here we test permutations
if (!( (Math::are_vector_equal(3, bary1.storage(), first_bary) &&
Math::are_vector_equal(3, bary2.storage(), second_bary) ) ||
(Math::are_vector_equal(3, bary1.storage(), second_bary) &&
Math::are_vector_equal(3, bary2.storage(), first_bary) ) ))
return EXIT_FAILURE;
// Testing a segment completely inside one element
Point a(0.05, 0.05, 0.05),
b(0.06, 0.06, 0.06);
Segment inside_segment(a, b);
intersector.computeIntersectionQuery(inside_segment);
test.element = interface_mesh.getNbElement(_segment_2) - 1;
interface_mesh.getBarycenter(test, bary);
Real third_bary[] = {0.055, 0.055, 0.055};
if (!Math::are_vector_equal(3, bary.storage(), third_bary))
return EXIT_FAILURE;
// Testing a segment whose end points are inside elements
Point c(0.1, 0.1, 0.1),
d(0.9, 0.9, 0.9);
Segment crossing_segment(c, d);
intersector.computeIntersectionQuery(crossing_segment);
UInt el1 = interface_mesh.getNbElement(_segment_2) - 2;
UInt el2 = el1 + 1;
test.element = el1;
interface_mesh.getBarycenter(test, bary1);
test.element = el2;
interface_mesh.getBarycenter(test, bary2);
Real fourth_bary[] = {13./60., 13./60., 13./60.};
Real fifth_bary[] = {37./60., 37./60., 37./60.};
// We don't know the order of the elements, so here we test permutations
if (!( (Math::are_vector_equal(3, bary1.storage(), fourth_bary) &&
Math::are_vector_equal(3, bary2.storage(), fifth_bary) ) ||
(Math::are_vector_equal(3, bary1.storage(), fifth_bary) &&
Math::are_vector_equal(3, bary2.storage(), fourth_bary) ) ))
return EXIT_FAILURE;
// Testing a segment along the edge of elements
Point e(1, 0, 0),
f(0, 1, 0);
Segment edge_segment(e, f);
UInt current_nb_elements = interface_mesh.getNbElement(_segment_2);
intersector.computeIntersectionQuery(edge_segment);
if (interface_mesh.getNbElement(_segment_2) != current_nb_elements + 1)
return EXIT_FAILURE;
test.element = interface_mesh.getNbElement(_segment_2) - 1;
interface_mesh.getBarycenter(test, bary);
Real sixth_bary[] = {0.5, 0.5, 0};
if (!Math::are_vector_equal(3, bary.storage(), sixth_bary))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
diff --git a/test/test_geometry/test_segment_intersection_triangle_3.cc b/test/test_geometry/test_segment_intersection_triangle_3.cc
index 7659e1f84..bdf95a508 100644
--- a/test/test_geometry/test_segment_intersection_triangle_3.cc
+++ b/test/test_geometry/test_segment_intersection_triangle_3.cc
@@ -1,145 +1,145 @@
/**
* @file test_segment_intersection_triangle_3.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
- * @author Clement Roux-Langlois <clement.roux@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
- * @date creation: Fri Mar 13 2015
- * @date last modification: Tue june 16 2015
+ * @date creation: Fri Feb 27 2015
+ * @date last modification: Thu Jan 14 2016
*
* @brief Tests the interface mesh generation
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_segment_intersector.hh"
#include "mesh_sphere_intersector.hh"
#include "geom_helper_functions.hh"
#include "mesh_geom_common.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef Cartesian K;
typedef Spherical SK;
/* -------------------------------------------------------------------------- */
int main (int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblError);
Math::setTolerance(1e-10);
Mesh mesh(2), interface_mesh(2, "interface_mesh");
mesh.read("test_geometry_triangle.msh");
MeshSegmentIntersector<2, _triangle_3> intersector(mesh, interface_mesh);
intersector.constructData();
// Testing a segment going out of the mesh
K::Point_3 a(0, 0.25, 0),
b(1, 0.25, 0),
c(0.25, 0, 0),
d(0.25, 1, 0);
K::Segment_3 h_interface(a, b),
v_interface(c, d);
std::list<K::Segment_3> interface_list;
interface_list.push_back(h_interface);
interface_list.push_back(v_interface);
intersector.computeIntersectionQueryList(interface_list);
if (interface_mesh.getNbElement(_segment_2) != 4)
return EXIT_FAILURE;
Vector<Real> bary(2);
Element test;
test.element = 0;
test.type = _segment_2;
interface_mesh.getBarycenter(test, bary);
Real first_bary[] = {0.125, 0.25};
if (!Math::are_vector_equal(2, bary.storage(), first_bary))
return EXIT_FAILURE;
// Testing a segment completely inside an element
K::Point_3 e(0.1, 0.33, 0),
f(0.1, 0.67, 0);
K::Segment_3 inside_segment(e, f);
intersector.computeIntersectionQuery(inside_segment);
test.element = interface_mesh.getNbElement(_segment_2) - 1;
interface_mesh.getBarycenter(test, bary);
Real second_bary[] = {0.1, 0.5};
if (!Math::are_vector_equal(2, bary.storage(), second_bary))
return EXIT_FAILURE;
#if 0
// Spherical kernel testing the addition of nodes
std::cout << "initial mesh size = " << mesh.getNodes().getSize() << " nodes" << std::endl;
SK::Sphere_3 sphere(SK::Point_3(0, 1, 0), 0.2*0.2);
SK::Sphere_3 sphere2(SK::Point_3(1, 0, 0), 0.4999999999);
MeshSphereIntersector<2, _triangle_3> intersector_sphere(mesh);
intersector_sphere.constructData();
std::list<SK::Sphere_3> sphere_list;
sphere_list.push_back(sphere);
sphere_list.push_back(sphere2);
intersector_sphere.computeIntersectionQueryList(sphere_list);
std::cout << "final mesh size = " << mesh.getNodes().getSize() << std::endl;
const Array<UInt> new_node_triangle_3 = intersector_sphere.getNewNodePerElem();
const Array<Real> & nodes = mesh.getNodes();
std::cout << "New nodes :" << std::endl;
std::cout << "node 5, x=" << nodes(4,0) << ", y=" << nodes(4,1) << std::endl;
std::cout << "node 6, x=" << nodes(5,0) << ", y=" << nodes(5,1) << std::endl;
std::cout << "node 7, x=" << nodes(6,0) << ", y=" << nodes(6,1) << std::endl;
if ( (new_node_triangle_3(0,0) != 1) || (new_node_triangle_3(1,0) != 2)){
for(UInt k=0; k != new_node_triangle_3.getSize(); ++k){
std::cout << new_node_triangle_3(k,0) << " new nodes in element " << k << ", node(s): "
<< new_node_triangle_3(k,1) << ", " << new_node_triangle_3(k,3)
<< ", on segment(s):" << new_node_triangle_3(k,2) << ", "
<< new_node_triangle_3(k,4) << std::endl;
}
return EXIT_FAILURE;
}
#endif
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_io/CMakeLists.txt b/test/test_io/CMakeLists.txt
index c80a4b39a..20424325c 100644
--- a/test/test_io/CMakeLists.txt
+++ b/test/test_io/CMakeLists.txt
@@ -1,34 +1,35 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Nov 13 2013
-# @date last modification: Tue Sep 02 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Sun Oct 19 2014
#
# @brief configuration for tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_parser "Test the input file parser")
add_akantu_test(test_dumper "Test the dumping of output files")
\ No newline at end of file
diff --git a/test/test_io/test_dumper/CMakeLists.txt b/test/test_io/test_dumper/CMakeLists.txt
index 954f17636..43f629851 100644
--- a/test/test_io/test_dumper/CMakeLists.txt
+++ b/test/test_io/test_dumper/CMakeLists.txt
@@ -1,38 +1,39 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author David Simon Kammer <david.kammer@epfl.ch>
#
-# @date creation: Tue Sep 02 2014
-# @date last modification: Tue Sep 02 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Fri Aug 14 2015
#
# @brief configuration for tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
register_test(test_dumper
SOURCES test_dumper.cc
FILES_TO_COPY input_file.dat test_dumper.msh
DIRECTORIES_TO_CREATE paraview
PACKAGE iohelper
)
diff --git a/test/test_io/test_dumper/test_dumper.cc b/test/test_io/test_dumper/test_dumper.cc
index bb35e8dbb..d2ca33a2c 100644
--- a/test/test_io/test_dumper/test_dumper.cc
+++ b/test/test_io/test_dumper/test_dumper.cc
@@ -1,162 +1,162 @@
/**
* @file test_dumper.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief test dumper
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "dumper_text.hh"
#include "dumper_variable.hh"
#include "dumper_paraview.hh"
#include "dumper_nodal_field.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("input_file.dat", argc, argv);
UInt spatial_dimension = 3;
Mesh mesh(spatial_dimension);
mesh.read("test_dumper.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
SolidMechanicsModel model(mesh);
MeshDataMaterialSelector<std::string> mat_selector("physical_names", model);
model.setMaterialSelector(mat_selector);
model.initFull();
model.setIncrementFlagOn();
model.updateResidual();
Real time_step = 0.1;
const Array<Real> & coord = mesh.getNodes();
Array<Real> & disp = model.getDisplacement();
Array<bool> & bound = model.getBlockedDOFs();
for (UInt n=0; n<mesh.getNbNodes(); ++n) {
Real dist = 0.;
for (UInt d=0; d<spatial_dimension; ++d) {
dist += coord(n,d) * coord(n,d);
}
dist = sqrt(dist);
for (UInt d=0; d<spatial_dimension; ++d) {
disp(n,d) = (d+1) * dist;
bound(n,d) = bool((n % 2) + d);
}
}
// dump boundary bottom as reference
model.setGroupDirectory("paraview", "Bottom");
model.setGroupBaseName("paraview_bottom", "Bottom");
model.addDumpGroupField("displacement", "Bottom");
model.addDumpGroupField("blocked_dofs", "Bottom");
UInt nbp = 3;
DumperParaview prvdumper("paraview_bottom_parallel",
"paraview",
false);
iohelper::Dumper & prvdpr = prvdumper.getDumper();
for (UInt p=0; p<nbp; ++p) {
prvdpr.setParallelContext(p, nbp, 0);
if (p != 0) {
prvdumper.unRegisterField("connectivities");
prvdumper.unRegisterField("element_type");
prvdumper.unRegisterField("positions");
prvdumper.unRegisterField("displacement");
}
prvdumper.registerFilteredMesh(mesh,
mesh.getElementGroup("Bottom").getElements(),
mesh.getElementGroup("Bottom").getNodes());
prvdumper.registerField("displacement",
new dumper::NodalField<Real,true>(model.getDisplacement(),
0,
0,
&(mesh.getElementGroup("Bottom").getNodes())));
prvdumper.dump(0);
}
DumperText txtdumper("text_bottom", iohelper::_tdm_csv);
txtdumper.setDirectory("paraview");
txtdumper.setPrecision(8);
txtdumper.setTimeStep(time_step);
txtdumper.registerFilteredMesh(mesh,
mesh.getElementGroup("Bottom").getElements(),
mesh.getElementGroup("Bottom").getNodes());
txtdumper.registerField("displacement",
new dumper::NodalField<Real,true>(model.getDisplacement(),
0,
0,
&(mesh.getElementGroup("Bottom").getNodes())));
txtdumper.registerField("blocked_dofs",
new dumper::NodalField<bool,true>(model.getBlockedDOFs(),
0,
0,
&(mesh.getElementGroup("Bottom").getNodes())));
Real pot_energy = 1.2345567891;
Vector<Real> gforces(2,1.);
txtdumper.registerVariable("potential_energy",
new dumper::Variable<Real>(pot_energy));
txtdumper.registerVariable("global_forces",
new dumper::Variable< Vector<Real> >(gforces));
// dump a first time before the main loop
model.dumpGroup("Bottom");
txtdumper.dump();
Real time = 0.;
for (UInt i=1; i<5; ++i) {
pot_energy += 2.;
gforces(0) += 0.1;
gforces(1) += 0.2;
// pre -> cor
// increment time after all steps of integration
time += time_step;
// dump after time increment
if (i%2 == 0) {
txtdumper.dump(time,i);
model.dumpGroup("Bottom");
// parallel test
for (UInt p=0; p<nbp; ++p) {
prvdpr.setParallelContext(p, nbp, 0);
prvdumper.dump(i);
}
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_io/test_parser/CMakeLists.txt b/test/test_io/test_parser/CMakeLists.txt
index 06285dee7..1d92eab1b 100644
--- a/test/test_io/test_parser/CMakeLists.txt
+++ b/test/test_io/test_parser/CMakeLists.txt
@@ -1,37 +1,38 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Nov 13 2013
-# @date last modification: Wed Nov 13 2013
+# @date creation: Fri Sep 03 2010
+# @date last modification: Tue Dec 02 2014
#
# @brief configuration for tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
register_test(test_parser
SOURCES test_parser.cc
FILES_TO_COPY input_file.dat
PACKAGE core
)
diff --git a/test/test_io/test_parser/test_parser.cc b/test/test_io/test_parser/test_parser.cc
index 21bb40855..d847058b9 100644
--- a/test/test_io/test_parser/test_parser.cc
+++ b/test/test_io/test_parser/test_parser.cc
@@ -1,76 +1,76 @@
/**
* @file test_parser.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
- * @date last modification: Thu Apr 03 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief test the input file parser
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "aka_random_generator.hh"
#include <iostream>
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("input_file.dat", argc, argv);
const Parser & p = getStaticParser();
std::cout << RandGenerator<Real>::seed() <<"==123456" << std::endl;
std::cout << p << std::endl;
Real toto = p.getParameter("toto");
std::cout << toto;
Real ref = 2*M_PI + std::max(2., 50.);
if(std::abs(toto - ref) > std::numeric_limits<Real>::epsilon()) {
std::cout << "!=" << ref << std::endl;
return 1;
}
std::cout << "==" << ref << std::endl;
Vector<Real> vect = p.getParameter("vect");
std::cout << vect << std::endl;
Matrix<Real> mat = p.getParameter("mat");
std::cout << mat << std::endl;
RandomParameter<Real> rand1 = p.getParameter("rand1");
std::cout << rand1 << std::endl;
RandomParameter<Real> rand2 = p.getParameter("rand2");
std::cout << rand2 << std::endl;
RandomParameter<Real> rand3 = p.getParameter("rand3");
std::cout << rand3 << std::endl;
finalize();
return 0;
}
diff --git a/test/test_mesh_utils/CMakeLists.txt b/test/test_mesh_utils/CMakeLists.txt
index 1b12b430c..70f83bed2 100644
--- a/test/test_mesh_utils/CMakeLists.txt
+++ b/test/test_mesh_utils/CMakeLists.txt
@@ -1,49 +1,50 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Feb 07 2011
-# @date last modification: Tue Nov 06 2012
+# @date creation: Fri Oct 22 2010
+# @date last modification: Fri Sep 18 2015
#
# @brief configuration for MeshUtils tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
#===============================================================================
# List of tests
#===============================================================================
add_akantu_test(test_mesh_io "Test mesh io object")
add_akantu_test(test_pbc_tweak "Test pbc facilities")
add_akantu_test(test_buildfacets "Tests for the generation of facets")
add_akantu_test(test_segment_nodetype "segment_nodetype")
register_test(test_purify_mesh
SOURCES test_purify_mesh.cc
FILES_TO_COPY purify_mesh.msh
PACKAGE core
)
add_akantu_test(test_mesh_partitionate "Test mesh partition creation")
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
index 8232dff96..9f814dc7b 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
@@ -1,140 +1,143 @@
/**
- * @file test_cohesive_buildfacets_hexahedron_20.cc
+ * @file test_buildfacets_hexahedron_20.cc
*
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date Wed Oct 03 10:20:53 2012
+ * @date creation: Tue May 08 2012
+ * @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with hexahedrons
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _hexahedron_20;
Mesh mesh(spatial_dimension);
mesh.read("hexahedron_20.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// std::cout << mesh_facets << std::endl;
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
std::cout << type << " " << i << " connected to ";
for (UInt j = 0; j < 6; ++j){
std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 4; ++j){
std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
index f65c850af..1ea23ee9c 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
@@ -1,141 +1,144 @@
/**
- * @file test_cohesive_buildfacets_hexahedron_8.cc
+ * @file test_buildfacets_hexahedron_8.cc
*
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date Wed Oct 03 10:20:53 2012
+ * @date creation: Tue May 08 2012
+ * @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with hexahedrons
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _hexahedron_8;
Mesh mesh(spatial_dimension);
mesh.read("hexahedron_8.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// std::cout << mesh_facets << std::endl;
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
std::cout << type << " " << i << " connected to ";
for (UInt j = 0; j < 6; ++j){
std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 4; ++j){
std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
index 9b3400949..05aa17362 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
@@ -1,127 +1,128 @@
/**
- * @file test_cohesive_buildfacets_mixed2d_linear.cc
+ * @file test_buildfacets_mixed2d_linear.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 19 10:20:53 2015
+ * @date creation: Fri Sep 18 2015
+ * @date last modification: Sat Sep 19 2015
*
- * @brief Test to check the building of the facets. Mesh with quadrangles
- * and triangles
+ * @brief Test to check the building of the facets. Mesh with quadrangles
+ * and triangles
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type1 = _quadrangle_4;
const ElementType type2 = _triangle_3;
Mesh mesh(spatial_dimension);
mesh.read("mixed2d_linear.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
const ElementType type_facet = mesh.getFacetType(type1);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type1);
const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type2);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_1.getSize(); ++i) {
std::cout << type1 << " " << i << " connected to ";
for (UInt j = 0; j < 4; ++j){
std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el2_2.getSize(); ++i) {
std::cout << type2 << " " << i << " connected to ";
for (UInt j = 0; j < 3; ++j){
std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
index 3d9f0dd61..96bbd9bda 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
@@ -1,127 +1,128 @@
/**
- * @file test_cohesive_buildfacets_mixed2d_quadratic.cc
+ * @file test_buildfacets_mixed2d_quadratic.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 19 10:20:53 2015
+ * @date creation: Fri Sep 18 2015
+ * @date last modification: Sat Sep 19 2015
*
- * @brief Test to check the building of the facets. Mesh with quadrangles
- * and triangles
+ * @brief Test to check the building of the facets. Mesh with quadrangles
+ * and triangles
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type1 = _quadrangle_8;
const ElementType type2 = _triangle_6;
Mesh mesh(spatial_dimension);
mesh.read("mixed2d_quadratic.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
const ElementType type_facet = mesh.getFacetType(type1);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type1);
const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type2);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_1.getSize(); ++i) {
std::cout << type1 << " " << i << " connected to ";
for (UInt j = 0; j < 4; ++j){
std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el2_2.getSize(); ++i) {
std::cout << type2 << " " << i << " connected to ";
for (UInt j = 0; j < 3; ++j){
std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
index 347575b18..13fd0dd0e 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
@@ -1,165 +1,167 @@
/**
- * @file test_cohesive_buildfacets_mixed3d_linear.cc
+ * @file test_buildfacets_mixed3d_linear.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 18 10:20:53 2015
+ * @date creation: Tue May 08 2012
+ * @date last modification: Sat Sep 19 2015
*
- * @brief Test to check the building of the facets. Mesh with hexahedrons
- * and pentahedrons
+ * @brief Test to check the building of the facets. Mesh with hexahedrons
+ * and pentahedrons
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type1 = _hexahedron_8;
const ElementType type2 = _pentahedron_6;
Mesh mesh(spatial_dimension);
mesh.read("mixed3d_linear.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
const ElementType type_facet1 = mesh.getFacetType(type1);
const ElementType type_facet2 = mesh.getFacetType(type2);
const ElementType type_subfacet = mesh.getFacetType(type_facet1);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel3_1 = mesh_facets.getElementToSubelement(type_facet1);
const Array< std::vector<Element> > & el_to_subel3_2 = mesh_facets.getElementToSubelement(type_facet2);
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3_1.getSize(); ++i) {
std::cout << type_facet1 << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel3_1(i)[j].type << " " << el_to_subel3_1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < el_to_subel3_2.getSize(); ++i) {
std::cout << type_facet2 << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel3_2(i)[j].type << " " << el_to_subel3_2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el3_1 = mesh_facets.getSubelementToElement(type1);
const Array<Element> & subel_to_el3_2 = mesh_facets.getSubelementToElement(type2);
const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type_facet1);
const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type_facet2);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3_1.getSize(); ++i) {
std::cout << type1 << " " << i << " connected to ";
for (UInt j = 0; j < 6; ++j){
std::cout << subel_to_el3_1(i, j).type << " " << subel_to_el3_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el3_2.getSize(); ++i) {
std::cout << type2 << " " << i << " connected to ";
for (UInt j = 0; j < 5; ++j){
std::cout << subel_to_el3_2(i, j).type << " " << subel_to_el3_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_1.getSize(); ++i) {
std::cout << type_facet1 << " " << i << " connected to ";
for (UInt j = 0; j < 4; ++j){
std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el2_2.getSize(); ++i) {
std::cout << type_facet2 << " " << i << " connected to ";
for (UInt j = 0; j < 3; ++j){
std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
index 082df996c..4ebdd56d5 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
@@ -1,167 +1,169 @@
/**
- * @file test_cohesive_buildfacets_mixed3d_quadratic.cc
+ * @file test_buildfacets_mixed3d_quadratic.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 18 10:20:53 2015
+ * @date creation: Tue May 08 2012
+ * @date last modification: Sat Sep 19 2015
*
- * @brief Test to check the building of the facets. Mesh with hexahedrons
- * and pentahedrons
+ * @brief Test to check the building of the facets. Mesh with hexahedrons
+ * and pentahedrons
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type1 = _hexahedron_20;
const ElementType type2 = _pentahedron_15;
Mesh mesh(spatial_dimension);
mesh.read("mixed3d_quadratic.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
const ElementType type_facet1 = mesh.getFacetType(type1);
const ElementType type_facet2 = mesh.getFacetType(type2);
const ElementType type_subfacet = mesh.getFacetType(type_facet1);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel3_1 = mesh_facets.getElementToSubelement(type_facet1);
const Array< std::vector<Element> > & el_to_subel3_2 = mesh_facets.getElementToSubelement(type_facet2);
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3_1.getSize(); ++i) {
std::cout << type_facet1 << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel3_1(i)[j].type << " " << el_to_subel3_1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < el_to_subel3_2.getSize(); ++i) {
std::cout << type_facet2 << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel3_2(i)[j].type << " " << el_to_subel3_2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el3_1 = mesh_facets.getSubelementToElement(type1);
const Array<Element> & subel_to_el3_2 = mesh_facets.getSubelementToElement(type2);
const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type_facet1);
const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type_facet2);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3_1.getSize(); ++i) {
std::cout << type1 << " " << i << " connected to ";
for (UInt j = 0; j < 6; ++j){
std::cout << subel_to_el3_1(i, j).type << " " << subel_to_el3_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el3_2.getSize(); ++i) {
std::cout << type2 << " " << i << " connected to ";
for (UInt j = 0; j < 5; ++j){
std::cout << subel_to_el3_2(i, j).type << " " << subel_to_el3_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_1.getSize(); ++i) {
std::cout << type_facet1 << " " << i << " connected to ";
for (UInt j = 0; j < 4; ++j){
std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_2.getSize(); ++i) {
std::cout << type_facet2 << " " << i << " connected to ";
for (UInt j = 0; j < 3; ++j){
std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
index 9a2519d54..208ed4af1 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
@@ -1,146 +1,148 @@
/**
- * @file test_cohesive_buildfacets_hexahedron.cc
+ * @file test_buildfacets_pentahedron_15.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 18 10:20:53 2015
+ * @date creation: Tue May 08 2012
+ * @date last modification: Mon Sep 28 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _pentahedron_15;
Mesh mesh(spatial_dimension);
mesh.read("pentahedron_15.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
Vector<ElementType> types_facet = mesh.getAllFacetTypes(type);
const ElementType type_subfacet = mesh.getFacetType(types_facet(0));
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
for (UInt ft = 0; ft < types_facet.size(); ++ft) {
ElementType type_facet = types_facet(ft);
Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
}
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
std::cout << type << " " << i << " connected to ";
for (UInt j = 0; j < subel_to_el3.getNbComponent(); ++j){
std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt ft = 0; ft < types_facet.size(); ++ft) {
ElementType type_facet = types_facet(ft);
Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < subel_to_el2.getNbComponent(); ++j){
std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
}
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < subel_to_el1.getNbComponent(); ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
index 573205d65..b11759516 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
@@ -1,146 +1,148 @@
/**
- * @file test_cohesive_buildfacets_hexahedron.cc
+ * @file test_buildfacets_pentahedron_6.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 18 10:20:53 2015
+ * @date creation: Tue May 08 2012
+ * @date last modification: Mon Sep 28 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _pentahedron_6;
Mesh mesh(spatial_dimension);
mesh.read("pentahedron_6.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
Vector<ElementType> types_facet = mesh.getAllFacetTypes(type);
const ElementType type_subfacet = mesh.getFacetType(types_facet(0));
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
for (UInt ft = 0; ft < types_facet.size(); ++ft) {
ElementType type_facet = types_facet(ft);
Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
}
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
std::cout << type << " " << i << " connected to ";
for (UInt j = 0; j < subel_to_el3.getNbComponent(); ++j){
std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt ft = 0; ft < types_facet.size(); ++ft) {
ElementType type_facet = types_facet(ft);
Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < subel_to_el2.getNbComponent(); ++j){
std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
}
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < subel_to_el1.getNbComponent(); ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
index 81f68854e..52d73dd7b 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
@@ -1,115 +1,116 @@
/**
- * @file test_cohesive_buildfacets_quadrangle_4.cc
+ * @file test_buildfacets_quadrangle_4.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 18 10:20:53 2015
+ * @date creation: Fri Sep 18 2015
+ * @date last modification: Sat Sep 19 2015
*
- * @brief Test to check the building of the facets. Mesh with quadrangles
+ * @brief Test to check the building of the facets. Mesh with quadrangles
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type = _quadrangle_4;
Mesh mesh(spatial_dimension);
mesh.read("quadrangle_4.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
std::cout << type << " " << i << " connected to ";
for (UInt j = 0; j < 4; ++j){
std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
index af1672fbd..0072e9aa5 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
@@ -1,115 +1,116 @@
/**
- * @file test_cohesive_buildfacets_quadrangle_8.cc
+ * @file test_buildfacets_quadrangle_8.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 18 10:20:53 2015
+ * @date creation: Fri Sep 18 2015
+ * @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with quadrangles
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type = _quadrangle_8;
Mesh mesh(spatial_dimension);
mesh.read("quadrangle_8.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
std::cout << type << " " << i << " connected to ";
for (UInt j = 0; j < 4; ++j){
std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
index 1fc131813..70495db8b 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
@@ -1,141 +1,143 @@
/**
- * @file test_cohesive_buildfacets_tetrahedron.cc
+ * @file test_buildfacets_tetrahedron_10.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date Wed Oct 03 10:20:53 2012
+ * @date creation: Tue May 08 2012
+ * @date last modification: Sat Sep 19 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _tetrahedron_10;
Mesh mesh(spatial_dimension);
mesh.read("tetrahedron_10.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// std::cout << mesh_facets << std::endl;
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
std::cout << type << " " << i << " connected to ";
for (UInt j = 0; j < 4; ++j){
std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 3; ++j){
std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
index 674405ce2..383648403 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
@@ -1,115 +1,116 @@
/**
- * @file test_cohesive_buildfacets_triangle_3.cc
+ * @file test_buildfacets_triangle_3.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 18 10:20:53 2015
+ * @date creation: Fri Sep 18 2015
+ * @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with triangles
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type = _triangle_3;
Mesh mesh(spatial_dimension);
mesh.read("triangle_3.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
std::cout << type << " " << i << " connected to ";
for (UInt j = 0; j < 3; ++j){
std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
index fb2fcf5c5..5e0a5f12d 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
@@ -1,115 +1,116 @@
/**
- * @file test_cohesive_buildfacets_triangle_6.cc
+ * @file test_buildfacets_triangle_6.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date Fri Sep 18 10:20:53 2015
+ * @date creation: Fri Sep 18 2015
+ * @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with triangles
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type = _triangle_6;
Mesh mesh(spatial_dimension);
mesh.read("triangle_6.msh");
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
std::cout << type << " " << i << " connected to ";
for (UInt j = 0; j < 3; ++j){
std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
for (UInt j = 0; j < 2; ++j){
std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_mesh_io/CMakeLists.txt b/test/test_mesh_utils/test_mesh_io/CMakeLists.txt
index f6ab66dbb..0f4e103ac 100644
--- a/test/test_mesh_utils/test_mesh_io/CMakeLists.txt
+++ b/test/test_mesh_utils/test_mesh_io/CMakeLists.txt
@@ -1,54 +1,55 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Fri Sep 03 2010
-# @date last modification: Fri May 03 2013
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for MeshIO tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_msh_cube cube.geo 3 1)
add_mesh(test_msh_cube_physical_names cube_physical_names.geo 3 1)
register_test(test_mesh_io_msh
SOURCES test_mesh_io_msh.cc
DEPENDS test_msh_cube
DIRECTORIES_TO_CREATE paraview
PACKAGE core
)
register_test(test_mesh_io_msh_physical_names
SOURCES test_mesh_io_msh_physical_names.cc
DEPENDS test_msh_cube_physical_names
PACKAGE core
)
#===============================================================================
#register_test(test_mesh_io_diana test_mesh_io_diana.cc)
#copy_files(test_mesh_io_diana dam.dat)
#file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview/mesh_io_diana)
diff --git a/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh.cc b/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh.cc
index 057d7cb2e..2313f57b8 100644
--- a/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh.cc
+++ b/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh.cc
@@ -1,53 +1,54 @@
/**
* @file test_mesh_io_msh.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Sep 03 2010
- * @date last modification: Fri May 10 2013
+ * @date creation: Thu Jul 15 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief unit test for the MeshIOMSH class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <cstdlib>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
akantu::MeshIOMSH mesh_io;
akantu::Mesh mesh(3);
mesh_io.read("./cube.msh", mesh);
std::cout << mesh << std::endl;
mesh_io.write("./cube.out", mesh);
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh_physical_names.cc b/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh_physical_names.cc
index 4f7f75952..bf2775f1e 100644
--- a/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh_physical_names.cc
+++ b/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh_physical_names.cc
@@ -1,58 +1,58 @@
/**
* @file test_mesh_io_msh_physical_names.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
*
* @date creation: Fri May 03 2013
- * @date last modification: Wed Nov 13 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief unit test for the MeshIOMSH physical names class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <iostream>
#include <sstream>
#include "aka_common.hh"
#include "mesh.hh"
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char* argv[]) {
UInt spatialDimension(3);
akantu::initialize(argc, argv);
Mesh mesh(spatialDimension);
mesh.read("./cube_physical_names.msh");
std::stringstream sstr;
for(Mesh::type_iterator type_it = mesh.firstType(); type_it != mesh.lastType(); ++type_it) {
const Array<std::string> & name_vec = mesh.getData<std::string>("physical_names", *type_it);
for(UInt i(0); i < name_vec.getSize(); i++) {
std::cout << "Element " << i << " (of type " << *type_it << ") has physical name " << name_vec(i) << "." << std::endl;
}
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_mesh_partitionate/CMakeLists.txt b/test/test_mesh_utils/test_mesh_partitionate/CMakeLists.txt
index 9cbdc984a..39d870d49 100644
--- a/test/test_mesh_utils/test_mesh_partitionate/CMakeLists.txt
+++ b/test/test_mesh_utils/test_mesh_partitionate/CMakeLists.txt
@@ -1,52 +1,55 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Dana Christen <dana.christen@gmail.com>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Fri Sep 03 2010
-# @date last modification: Wed May 08 2013
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for mesh partitioner tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_mesh_partitionate_mesh
triangle.geo 2 2)
add_mesh(test_mesh_partitionate_mesh_data_mesh
quad.geo 2 1)
register_test(test_mesh_partitionate_scotch
SOURCES test_mesh_partitionate_scotch.cc
DEPENDS test_mesh_partitionate_mesh
DIRECTORIES_TO_CREATE paraview
PACKAGE scotch
)
register_test(test_mesh_partitionate_mesh_data
SOURCES test_mesh_partitionate_mesh_data.cc
DEPENDS test_mesh_partitionate_mesh_data_mesh
DIRECTORIES_TO_CREATE paraview
PACKAGE scotch
)
diff --git a/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc b/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc
index ad680a112..85c9ceac3 100644
--- a/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc
+++ b/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc
@@ -1,116 +1,116 @@
/**
* @file test_mesh_partitionate_mesh_data.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
*
* @date creation: Wed May 08 2013
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Mon May 18 2015
*
* @brief test of manual partitioner
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cmath>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_partition_mesh_data.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
#include "dumper_elemental_field.hh"
#endif //AKANTU_USE_IOHELPER
using namespace akantu;
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
initialize(argc, argv);
UInt dim = 2;
UInt nb_partitions = 8;
akantu::Mesh mesh(dim);
mesh.read("quad.msh");
ElementTypeMapArray<UInt> partition;
UInt nb_component = 1;
GhostType gt = _not_ghost;
Mesh::type_iterator tit = mesh.firstType(dim, gt);
Mesh::type_iterator tend = mesh.lastType(dim, gt);
for(; tit != tend; ++tit) {
UInt nb_element = mesh.getNbElement(*tit, gt);
partition.alloc(nb_element, nb_component, *tit, gt);
Array<UInt> & type_partition_reference = partition(*tit, gt);
for(UInt i(0); i < nb_element; ++i) {
Real barycenter[dim];
mesh.getBarycenter(i, *tit, barycenter, gt);
Real real_proc = barycenter[0] * nb_partitions;
if(std::abs(real_proc - round(real_proc)) < 10*std::numeric_limits<Real>::epsilon()) {
type_partition_reference(i) = round(real_proc);
} else {
std::cout << "*";
type_partition_reference(i) = floor(real_proc);
}
std::cout << "Assigned proc " << type_partition_reference(i) << " to elem " << i << " (type " << *tit << ", barycenter x-coordinate " << barycenter[0] << ")" << std::endl;
}
}
akantu::MeshPartitionMeshData * partitioner = new akantu::MeshPartitionMeshData(mesh, dim);
partitioner->setPartitionMapping(partition);
partitioner->partitionate(nb_partitions);
tit = mesh.firstType(dim, gt);
for(; tit != tend; ++tit) {
UInt nb_element = mesh.getNbElement(*tit, gt);
const Array<UInt> & type_partition_reference = partition(*tit, gt);
const Array<UInt> & type_partition = partitioner->getPartitions()(*tit, gt);
for(UInt i(0); i < nb_element; ++i) {
AKANTU_DEBUG_ASSERT(type_partition(i) == type_partition_reference(i), "Incorrect partitioning");
}
}
//#define DEBUG_TEST
#ifdef DEBUG_TEST
DumperParaview dumper("test-mesh-data-partition");
dumper::Field * field1 =
new dumper::ElementalField<UInt>(partitioner->getPartitions(), dim);
dumper::Field * field2 =
new dumper::ElementalField<UInt>(partition, dim);
dumper.registerMesh(mesh, dim);
dumper.registerField("partitions" , field1);
dumper.registerField("partitions_ref", field2);
dumper.dump();
#endif
delete partitioner;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_scotch.cc b/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_scotch.cc
index 97e1c0d29..20c797a21 100644
--- a/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_scotch.cc
+++ b/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_scotch.cc
@@ -1,77 +1,78 @@
/**
* @file test_mesh_partitionate_scotch.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Sep 01 2010
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Sun Sep 12 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of internal facet extraction
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "mesh.hh"
#include "mesh_partition_scotch.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
# include "dumper_elemental_field.hh"
#endif //AKANTU_USE_IOHELPER
using namespace akantu;
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
initialize(argc, argv);
debug::setDebugLevel(akantu::dblDump);
int dim = 2;
akantu::Mesh mesh(dim);
mesh.read("triangle.msh");
akantu::MeshPartition * partition = new akantu::MeshPartitionScotch(mesh, dim);
partition->partitionate(8);
#ifdef AKANTU_USE_IOHELPER
DumperParaview dumper("test-scotch-partition");
dumper::Field * field = new dumper::ElementalField<UInt>(partition->getPartitions(),
dim);
dumper.registerMesh(mesh, dim);
dumper.registerField("partitions", field);
dumper.dump();
#endif //AKANTU_USE_IOHELPER
partition->reorder();
mesh.write("triangle_reorder.msh");
delete partition;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_pbc_tweak/CMakeLists.txt b/test/test_mesh_utils/test_pbc_tweak/CMakeLists.txt
index cdcb5fde8..922aab9e8 100644
--- a/test/test_mesh_utils/test_pbc_tweak/CMakeLists.txt
+++ b/test/test_mesh_utils/test_pbc_tweak/CMakeLists.txt
@@ -1,42 +1,43 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
-# @date creation: Wed Feb 09 2011
-# @date last modification: Tue Nov 06 2012
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for pcb tweal test
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_pbc_cube_mesh cube.geo 3 1)
register_test(test_pbc_tweak
SOURCES test_pbc_tweak.cc
DEPENDS test_pbc_cube_mesh
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE core
)
diff --git a/test/test_mesh_utils/test_pbc_tweak/test_pbc_tweak.cc b/test/test_mesh_utils/test_pbc_tweak/test_pbc_tweak.cc
index 8062542e3..f3d7081d0 100644
--- a/test/test_mesh_utils/test_pbc_tweak/test_pbc_tweak.cc
+++ b/test/test_mesh_utils/test_pbc_tweak/test_pbc_tweak.cc
@@ -1,68 +1,69 @@
/**
* @file test_pbc_tweak.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
- * @date creation: Wed Feb 09 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Aug 20 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of internal facet extraction
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[])
{
int dim = 3;
initialize("material.dat", argc, argv);
debug::setDebugLevel(akantu::dblInfo);
Mesh mesh(dim);
mesh.read("cube.msh");
SolidMechanicsModel model(mesh);
/* -------------------------------------------------------------------------- */
model.initFull();
/* -------------------------------------------------------------------------- */
model.setPBC(1,1,1);
model.initPBC();
model.assembleMassLumped();
/* -------------------------------------------------------------------------- */
model.setBaseName("test-pbc-tweak");
model.addDumpField("mass");
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_purify_mesh.cc b/test/test_mesh_utils/test_purify_mesh.cc
index 83b7244ca..72de7434d 100644
--- a/test/test_mesh_utils/test_purify_mesh.cc
+++ b/test/test_mesh_utils/test_purify_mesh.cc
@@ -1,62 +1,63 @@
/**
* @file test_purify_mesh.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Jul 30 2012
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Thu Jul 15 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test the purifyMesh function from MeshUtils
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "mesh.hh"
#include "mesh_utils.hh"
#include "mesh_io.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
Mesh mesh(2);
MeshIOMSH mesh_io;
mesh_io.read("purify_mesh.msh", mesh);
MeshUtils::purifyMesh(mesh);
mesh_io.write("purify_mesh_after.msh", mesh);
if(mesh.getNbNodes() != 21)
AKANTU_DEBUG_ERROR("The purified mesh does not contain the good number of nodes.");
if(mesh.getNbElement(_quadrangle_8) != 4)
AKANTU_DEBUG_ERROR("The purified mesh does not contain the good number of element.");
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt b/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt
index 3c711cad5..aea1a0789 100644
--- a/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt
+++ b/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt
@@ -1,5 +1,34 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Marco Vocialta <marco.vocialta@epfl.ch>
+#
+# @date creation: Fri Sep 18 2015
+#
+# @brief CMakeLists for segment nodetype tests
+#
+# @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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
register_test(test_segment_nodetype
SOURCES test_segment_nodetype.cc
FILES_TO_COPY mesh.msh
PACKAGE parallel
)
diff --git a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
index aa36e6111..2c0cfecd8 100644
--- a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
+++ b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
@@ -1,104 +1,106 @@
/**
* @file test_segment_nodetype.cc
+ *
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @date Fri Sep 18 13:39:35 2015
*
- * @brief Test to verify that the node type is correctly associated to
+ * @date creation: Fri Sep 18 2015
+ *
+ * @brief Test to verify that the node type is correctly associated to
* the segments in parallel
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_utils.hh"
#include "distributed_synchronizer.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
UInt spatial_dimension = 3;
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
DistributedSynchronizer * dist = NULL;
// partition the mesh
if (prank == 0) {
mesh.read("mesh.msh");
MeshPartitionScotch partition(mesh, spatial_dimension);
partition.partitionate(psize);
dist = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, &partition);
} else {
dist = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
// compute the node types for each segment
Mesh mesh_facets(mesh.initMeshFacets());
MeshUtils::buildSegmentToNodeType(mesh, mesh_facets, dist);
// verify that the number of segments per node type makes sense
std::map<Int, UInt> nb_facets_per_nodetype;
UInt nb_segments = 0;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end();
++gt) {
GhostType ghost_type = *gt;
const Array<Int> & segment_to_nodetype = mesh_facets.getData<Int>("segment_to_nodetype",
_segment_2, ghost_type);
// count the number of segments per node type
for (UInt s = 0; s < segment_to_nodetype.getSize(); ++s) {
if (nb_facets_per_nodetype.find(segment_to_nodetype(s)) == nb_facets_per_nodetype.end())
nb_facets_per_nodetype[segment_to_nodetype(s)] = 1;
else
++nb_facets_per_nodetype[segment_to_nodetype(s)];
}
nb_segments += segment_to_nodetype.getSize();
}
// checking the solution
if (nb_segments != 24)
AKANTU_DEBUG_ERROR("The number of segments is wrong");
if (prank == 0) {
if (nb_facets_per_nodetype[-1] != 3 ||
nb_facets_per_nodetype[-2] != 9 ||
nb_facets_per_nodetype[-3] != 12)
AKANTU_DEBUG_ERROR("The segments of processor 0 have the wrong node type");
if (nb_facets_per_nodetype.size() > 3)
AKANTU_DEBUG_ERROR("Processor 0 cannot have any slave segment");
}
if (prank == psize - 1 && nb_facets_per_nodetype.find(-2) != nb_facets_per_nodetype.end())
AKANTU_DEBUG_ERROR("The last processor must not have any master facets");
finalize();
return 0;
}
diff --git a/test/test_model/CMakeLists.txt b/test/test_model/CMakeLists.txt
index 5bbd78924..2d6a5987c 100644
--- a/test/test_model/CMakeLists.txt
+++ b/test/test_model/CMakeLists.txt
@@ -1,38 +1,39 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
-# @date creation: Fri Nov 26 2010
-# @date last modification: Thu Jul 03 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Sat Sep 26 2015
#
# @brief configuration for model tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_solid_mechanics_model "Test for the solid mechanics model")
add_akantu_test(test_heat_transfer_model "Test for the heat transfer model")
add_akantu_test(test_structural_mechanics_model "Test for the structural mechanics model")
add_akantu_test(test_non_local_toolbox "Test of the functionalities in the non-local toolbox")
\ No newline at end of file
diff --git a/test/test_model/test_heat_transfer_model/CMakeLists.txt b/test/test_model/test_heat_transfer_model/CMakeLists.txt
index a16a1ef44..156841967 100644
--- a/test/test_model/test_heat_transfer_model/CMakeLists.txt
+++ b/test/test_model/test_heat_transfer_model/CMakeLists.txt
@@ -1,88 +1,89 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
-# @date creation: Sun May 01 2011
-# @date last modification: Tue Nov 06 2012
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for heat transfer model tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_heat_cube3d_mesh1 cube.geo 3 1 OUTPUT cube1.msh)
add_mesh(test_heat_square_mesh1 square.geo 2 1 OUTPUT square1.msh)
add_mesh(test_heat_line_mesh line.geo 1 1 OUTPUT line.msh)
register_test(test_heat_transfer_model_cube3d
SOURCES test_heat_transfer_model_cube3d.cc
DEPENDS test_heat_cube3d_mesh1 test_heat_square_mesh1 test_heat_line_mesh
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE heat_transfer
)
add_mesh(test_heat_cube_tet4 cube_tet.geo 3 1 OUTPUT cube_tet4.msh)
register_test(test_heat_transfer_model_cube3d_pbc
SOURCES test_heat_transfer_model_cube3d_pbc.cc
DEPENDS test_heat_cube_tet4
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE heat_transfer
)
add_mesh(test_heat_square_tri3 square_tri.geo 2 1 OUTPUT square_tri3.msh)
register_test(test_heat_transfer_model_square2d_pbc
SOURCES test_heat_transfer_model_square2d_pbc.cc
DEPENDS test_heat_square_tri3
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE heat_transfer
)
register_test(test_heat_transfer_model_square2d
SOURCES test_heat_transfer_model_square2d.cc
DEPENDS test_heat_square_tri3
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE heat_transfer
)
register_test(test_heat_transfer_model_square2d_implicit
SOURCES test_heat_transfer_model_square2d_implicit.cc
DEPENDS test_heat_square_tri3
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE heat_transfer
)
register_test(test_heat_transfer_model_cube3d_istropic_conductivity
SOURCES test_heat_transfer_model_cube3d_istropic_conductivity.cc
DEPENDS test_heat_cube3d_mesh1
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE heat_transfer
)
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d.cc
index 14712e43a..bf3b2c958 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d.cc
@@ -1,124 +1,126 @@
/**
* @file test_heat_transfer_model_cube3d.cc
*
- * @author Rui Wang <rui.wang@epfl.ch>
* @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
+ * @author Rui Wang <rui.wang@epfl.ch>
*
- * @date Sun May 01 19:14:43 2011
+ * @date creation: Sun May 01 2011
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "heat_transfer_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
UInt spatial_dimension = 3;
ElementType type = _tetrahedron_4;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
initialize("material.dat", argc, argv);
Mesh mesh(spatial_dimension);
MeshIOMSH mesh_io;
mesh_io.read("cube1.msh", mesh);
HeatTransferModel model(mesh);
//initialize everything
model.initFull();
//assemble the lumped capacity
model.assembleCapacityLumped();
//get and set stable time step
Real time_step = model.getStableTimeStep()*0.8;
std::cout << "time step is:" << time_step << std::endl;
model.setTimeStep(time_step);
/// boundary conditions
const Array<Real> & nodes = mesh.getNodes();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & temperature = model.getTemperature();
UInt nb_nodes = mesh.getNbNodes();
//double t1, t2;
double length;
// t1 = 300.;
// t2 = 100.;
length = 1.;
for (UInt i = 0; i < nb_nodes; ++i) {
//temperature(i) = t1 - (t1 - t2) * sin(nodes(i, 0) * M_PI / length);
temperature(i) = 100.;
//to insert a heat source
Real dx = nodes(i,0) - length/2.;
Real dy = nodes(i,1) - length/2.;
Real dz = nodes(i,2) - length/2.;
Real d = sqrt(dx*dx + dy*dy + dz*dz);
if(d < 0.1){
boundary(i) = true;
temperature(i) = 300.;
}
}
model.updateResidual();
model.setBaseName("heat_transfer_cube3d");
model.addDumpField("temperature" );
model.addDumpField("temperature_rate");
model.addDumpField("residual" );
model.addDumpField("capacity_lumped" );
model.dump();
// //for testing
int max_steps = 1000;
for(int i=0; i<max_steps; i++)
{
model.explicitPred();
model.updateResidual();
model.solveExplicitLumped();
model.explicitCorr();
if(i % 100 == 0) model.dump();
if(i % 10 == 0) std::cout << "Step " << i << "/" << max_steps << std::endl;
}
std::cout << "Stable Time Step is : " << time_step << std::endl;
return 0;
}
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_istropic_conductivity.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_istropic_conductivity.cc
index 24d720c96..9102a0f9f 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_istropic_conductivity.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_istropic_conductivity.cc
@@ -1,120 +1,122 @@
/**
* @file test_heat_transfer_model_cube3d_istropic_conductivity.cc
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Rui Wang <rui.wang@epfl.ch>
*
* @date creation: Sun May 01 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "heat_transfer_model.hh"
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
/* -------------------------------------------------------------------------- */
akantu::UInt spatial_dimension = 3;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
akantu::Mesh mesh(spatial_dimension);
akantu::MeshIOMSH mesh_io;
mesh_io.read("cube1.msh", mesh);
akantu::HeatTransferModel model(mesh);
//initialize everything
model.initFull();
//assemble the lumped capacity
model.assembleCapacityLumped();
//get stable time step
akantu::Real time_step = model.getStableTimeStep()*0.8;
cout<<"time step is:"<<time_step<<endl;
model.setTimeStep(time_step);
/// boundary conditions
const akantu::Array<akantu::Real> & nodes = model.getFEEngine().getMesh().getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<akantu::Real> & temperature = model.getTemperature();
akantu::Real eps = 1e-15;
double length = 1.;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
//temperature(i) = t1 - (t1 - t2) * sin(nodes(i, 0) * M_PI / length);
temperature(i) = 100.;
if(nodes(i,0) < eps) {
boundary(i) = true;
temperature(i) = 300.;
}
//set the second boundary condition
if(std::abs(nodes(i,0) - length) < eps) {
boundary(i) = true;
temperature(i) = 300.;
}
// //to insert a heat source
// if(std::abs(nodes(i,0) - length/2.) < 0.025 && std::abs(nodes(i,1) - length/2.) < 0.025 && std::abs(nodes(i,2) - length/2.) < 0.025) {
// boundary(i) = true;
// temperature(i) = 300.;
// }
}
model.updateResidual();
model.setBaseName("heat_transfer_cube3d_istropic_conductivity");
model.addDumpField("temperature" );
model.addDumpField("temperature_rate");
model.addDumpField("residual" );
model.addDumpField("capacity_lumped" );
model.dump();
// //for testing
int max_steps = 1000;
for(int i=0; i<max_steps; i++)
{
model.explicitPred();
model.updateResidual();
model.explicitCorr();
if(i % 100 == 0) model.dump();
if(i % 10000 == 0)
std::cout << "Step " << i << "/" << max_steps << std::endl;
}
cout<< "\n\n Stable Time Step is : " << time_step << "\n \n" <<endl;
return 0;
}
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_pbc.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_pbc.cc
index ab32f408c..3eb0d4dc6 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_pbc.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_pbc.cc
@@ -1,120 +1,121 @@
/**
* @file test_heat_transfer_model_cube3d_pbc.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
* @author Rui Wang <rui.wang@epfl.ch>
*
* @date creation: Sun May 01 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "mesh.hh"
#include "heat_transfer_model.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <fstream>
using namespace std;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
akantu::UInt spatial_dimension = 3;
//create mesh
akantu::Mesh mesh(spatial_dimension);
mesh.read("cube_tet4.msh");
akantu::HeatTransferModel model(mesh);
//initialize everything
model.initFull();
//initialize PBC
model.setPBC(1,1,1);
model.initPBC();
//assemble the lumped capacity
model.assembleCapacityLumped();
//get stable time step
akantu::Real time_step = model.getStableTimeStep()*0.8;
cout<<"time step is:"<<time_step<<endl;
model.setTimeStep(time_step);
// boundary conditions
const akantu::Array<akantu::Real> & nodes = model.getFEEngine().getMesh().getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<akantu::Real> & temperature = model.getTemperature();
// double t1, t2;
double length;
// t1 = 300.;
// t2 = 100.;
length = 1.;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
temperature(i) = 100.;
akantu::Real dx = nodes(i,0) - length/4.;
akantu::Real dy = nodes(i,1) - length/4.;
akantu::Real dz = nodes(i,2) - length/4.;
akantu::Real d = sqrt(dx*dx + dy*dy + dz*dz);
if(d < 0.1){
boundary(i) = true;
temperature(i) = 300.;
}
}
model.updateResidual();
model.setBaseName("heat_transfer_cube3d_pbc");
model.addDumpField("temperature" );
model.addDumpField("temperature_rate");
model.addDumpField("residual" );
model.addDumpField("capacity_lumped" );
model.dump();
/* ------------------------------------------------------------------------ */
// //for testing
int max_steps = 1000;
/* ------------------------------------------------------------------------ */
for(int i=0; i<max_steps; i++)
{
model.explicitPred();
model.updateResidual();
model.solveExplicitLumped();
model.explicitCorr();
if(i % 100 == 0) model.dump();
if(i % 10 == 0)
std::cout << "Step " << i << "/" << max_steps << std::endl;
}
cout<< "\n\n Stable Time Step is : " << time_step << "\n \n" <<endl;
return 0;
}
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d.cc
index 2e49e9446..36bee9169 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d.cc
@@ -1,111 +1,115 @@
/**
* @file test_heat_transfer_model_square2d.cc
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
*
- * @date Sun May 01 19:14:43 2011
+ * @date creation: Sun May 01 2011
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "heat_transfer_model.hh"
#include "pbc_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
/* -------------------------------------------------------------------------- */
akantu::UInt spatial_dimension = 2;
std::string base_name;
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
//create mesh
akantu::Mesh mesh(spatial_dimension);
mesh.read("square_tri3.msh");
akantu::HeatTransferModel model(mesh);
//initialize everything
model.initFull();
//assemble the lumped capacity
model.assembleCapacityLumped();
//get stable time step
akantu::Real time_step = model.getStableTimeStep()*0.8;
cout<<"time step is:" << time_step << endl;
model.setTimeStep(time_step);
//boundary conditions
const akantu::Array<akantu::Real> & nodes = model.getFEEngine().getMesh().getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<akantu::Real> & temperature = model.getTemperature();
double length;
length = 1.;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
temperature(i) = 100.;
akantu::Real dx = nodes(i,0) - length/4.;
akantu::Real dy = 0.0;
akantu::Real dz = 0.0;
if (spatial_dimension > 1) dy = nodes(i,1) - length/4.;
if (spatial_dimension == 3) dz = nodes(i,2) - length/4.;
akantu::Real d = sqrt(dx*dx + dy*dy + dz*dz);
// if(dx < 0.0){
if(d < 0.1){
boundary(i) = true;
temperature(i) = 300.;
}
}
model.updateResidual();
model.setBaseName("heat_transfer_square2d");
model.addDumpField("temperature" );
model.addDumpField("temperature_rate");
model.addDumpField("residual" );
model.addDumpField("capacity_lumped" );
model.dump();
//main loop
int max_steps = 1500;
for(int i=0; i<max_steps; i++)
{
model.explicitPred();
model.updateResidual();
model.solveExplicitLumped();
model.explicitCorr();
if(i % 100 == 0) model.dump();
if(i % 10 == 0)
std::cout << "Step " << i << "/" << max_steps << std::endl;
}
cout<< "\n\n Stable Time Step is : " << time_step << "\n \n" <<endl;
return 0;
}
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_implicit.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_implicit.cc
index 1703742e6..d4d09c1c2 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_implicit.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_implicit.cc
@@ -1,93 +1,95 @@
/**
- * @file test_heat_transfer_model_square2d.cc
+ * @file test_heat_transfer_model_square2d_implicit.cc
*
*
- * @date Sun May 01 19:14:43 2011
+ * @date creation: Sun May 01 2011
+ * @date last modification: Fri Jul 17 2015
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "heat_transfer_model.hh"
#include "pbc_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
/* -------------------------------------------------------------------------- */
akantu::UInt spatial_dimension = 2;
std::string base_name;
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
//create mesh
akantu::Mesh mesh(spatial_dimension);
mesh.read("square_tri3.msh");
akantu::HeatTransferModel model(mesh);
//initialize everything
model.initFull(akantu::HeatTransferModelOptions(akantu::_static));
//boundary conditions
const akantu::Array<akantu::Real> & nodes = model.getFEEngine().getMesh().getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<akantu::Real> & temperature = model.getTemperature();
double length;
length = 1.;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
temperature(i) = 100.;
akantu::Real dx = nodes(i,0) - length/4.;
akantu::Real dy = 0.0;
akantu::Real dz = 0.0;
if (spatial_dimension > 1) dy = nodes(i,1) - length/4.;
if (spatial_dimension == 3) dz = nodes(i,2) - length/4.;
akantu::Real d = sqrt(dx*dx + dy*dy + dz*dz);
// if(dx < 0.0){
if(d < 0.1){
boundary(i) = true;
temperature(i) = 300.;
}
}
model.assembleConductivityMatrix();
model.updateResidual();
model.setBaseName("heat_transfer_square2d");
model.addDumpField("temperature" );
model.addDumpField("temperature_rate");
model.addDumpField("residual" );
model.addDumpField("conductivity" );
model.dump();
model.solveStatic();
model.dump();
return 0;
}
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_pbc.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_pbc.cc
index e36bea10a..28112d6fe 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_pbc.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_pbc.cc
@@ -1,111 +1,113 @@
/**
* @file test_heat_transfer_model_square2d_pbc.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
- * @date Sun May 01 19:14:43 2011
+ * @date creation: Sun May 01 2011
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "heat_transfer_model.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
akantu::UInt spatial_dimension = 2;
akantu::initialize("material.dat", argc, argv);
//create mesh
akantu::Mesh mesh(spatial_dimension);
mesh.read("square_tri3.msh");
akantu::HeatTransferModel model(mesh);
//initialize everything
model.initFull();
//initialize PBC
model.setPBC(1,1,1);
model.initPBC();
//assemble the lumped capacity
model.assembleCapacityLumped();
//get stable time step
akantu::Real time_step = model.getStableTimeStep()*0.8;
cout<<"time step is:" << time_step << endl;
model.setTimeStep(time_step);
//boundary conditions
const akantu::Array<akantu::Real> & nodes = model.getFEEngine().getMesh().getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<akantu::Real> & temperature = model.getTemperature();
double length;
length = 1.;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
temperature(i) = 100.;
akantu::Real dx = nodes(i,0) - length/4.;
akantu::Real dy = 0.0;
akantu::Real dz = 0.0;
if (spatial_dimension > 1) dy = nodes(i,1) - length/4.;
if (spatial_dimension == 3) dz = nodes(i,2) - length/4.;
akantu::Real d = sqrt(dx*dx + dy*dy + dz*dz);
// if(dx < 0.0){
if(d < 0.1){
boundary(i) = true;
temperature(i) = 300.;
}
}
model.updateResidual();
model.setBaseName("heat_transfer_square_2d_pbc");
model.addDumpField("temperature" );
model.addDumpField("temperature_rate");
model.addDumpField("residual" );
model.addDumpField("capacity_lumped" );
model.dump();
//main loop
int max_steps = 1000;
for(int i=0; i<max_steps; i++)
{
model.explicitPred();
model.updateResidual();
model.solveExplicitLumped();
model.explicitCorr();
if(i % 100 == 0) model.dump();
if(i % 10 == 0)
std::cout << "Step " << i << "/" << max_steps << std::endl;
}
cout<< "\n\n Stable Time Step is : " << time_step << "\n \n" <<endl;
return 0;
}
diff --git a/test/test_model/test_non_local_toolbox/CMakeLists.txt b/test/test_model/test_non_local_toolbox/CMakeLists.txt
index 1e9b80be3..a00855e9f 100644
--- a/test/test_model/test_non_local_toolbox/CMakeLists.txt
+++ b/test/test_model/test_non_local_toolbox/CMakeLists.txt
@@ -1,74 +1,75 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
#
-# @date creation: Sun May 01 2011
-# @date last modification: Tue Nov 06 2012
+# @date creation: Sat Sep 26 2015
+# @date last modification: Wed Dec 16 2015
#
# @brief configuration for heat transfer model tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
#===============================================================================
register_test(test_non_local_neighborhood_base
SOURCES test_non_local_neighborhood_base.cc test_material.hh test_material.cc
FILES_TO_COPY material.dat plot_neighborhoods.py plate.msh
PACKAGE damage_non_local
)
register_test(test_weight_computation
SOURCES test_weight_computation.cc test_material.hh test_material.cc
FILES_TO_COPY material_weight_computation.dat plate.msh
PACKAGE damage_non_local
)
register_test(test_non_local_averaging
SOURCES test_non_local_averaging.cc test_material.hh test_material.cc
FILES_TO_COPY material_weight_computation.dat plate.msh
PACKAGE damage_non_local
)
register_test(test_remove_damage_weight_function
SOURCES test_remove_damage_weight_function.cc test_material_damage.hh test_material_damage.cc
FILES_TO_COPY material_remove_damage.dat plate.msh
PACKAGE damage_non_local
)
register_test(test_build_neighborhood_parallel
SOURCES test_build_neighborhood_parallel.cc test_material.hh test_material.cc
FILES_TO_COPY material_parallel_test.dat parallel_test.msh
PACKAGE damage_non_local
)
register_test(test_pair_computation
SOURCES test_pair_computation.cc test_material_damage.hh test_material_damage.cc
FILES_TO_COPY material_remove_damage.dat pair_test.msh
PACKAGE damage_non_local
)
register_test(test_pair_computation_parallel
SOURCES test_pair_computation.cc test_material_damage.hh test_material_damage.cc
FILES_TO_COPY material_remove_damage.dat pair_test.msh
PACKAGE damage_non_local
)
diff --git a/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
index 864920a23..c36cda52e 100644
--- a/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
+++ b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
@@ -1,184 +1,187 @@
/**
* @file test_build_neighborhood_parallel.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Sun Oct 11 11:20:23 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
*
* @brief test in parallel for the class NonLocalNeighborhood
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "test_material.hh"
#include "non_local_neighborhood_base.hh"
#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize("material_parallel_test.dat", argc, argv);
StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
// some configuration variables
const UInt spatial_dimension = 2;
// mesh creation and read
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
if(prank == 0) {
mesh.read("parallel_test.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModel model(mesh);
model.initParallel(partition);
delete partition;
/// dump the ghost elements before the non-local part is intialized
DumperParaview dumper_ghost("ghost_elements");
dumper_ghost.registerMesh(mesh, spatial_dimension, _ghost);
if(psize > 1) {
dumper_ghost.dump();
}
/// creation of material selector
MeshDataMaterialSelector<std::string> * mat_selector;
mat_selector = new MeshDataMaterialSelector<std::string>("physical_names", model);
model.setMaterialSelector(*mat_selector);
/// dump material index in paraview
model.addDumpField("partitions");
model.dump();
/// model initialization changed to use our material
model.initFull(SolidMechanicsModelOptions(_static, true));
model.registerNewCustomMaterials< TestMaterial<spatial_dimension> >("test_material");
model.initMaterials();
/// dump the ghost elements after ghosts for non-local have been added
if(psize > 1)
dumper_ghost.dump();
model.addDumpField("grad_u");
model.addDumpField("grad_u non local");
model.addDumpField("material_index");
/// apply constant strain field everywhere in the plate
Matrix<Real> applied_strain(spatial_dimension, spatial_dimension);
applied_strain.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
applied_strain(i,i) = 2.;
ElementType element_type = _triangle_3;
GhostType ghost_type = _not_ghost;
/// apply constant grad_u field in all elements
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
Material & mat = model.getMaterial(m);
Array<Real> & grad_u = const_cast<Array<Real> &> (mat.getInternal<Real>("grad_u")(element_type, ghost_type));
Array<Real>::iterator< Matrix<Real> > grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
Array<Real>::iterator< Matrix<Real> > grad_u_end = grad_u.end(spatial_dimension, spatial_dimension);
for (; grad_u_it != grad_u_end; ++grad_u_it)
(*grad_u_it) += applied_strain;
}
/// double the strain in the center: find the closed gauss point to the center
/// compute the quadrature points
ElementTypeMapReal quad_coords("quad_coords");
mesh.initElementTypeMapArray(quad_coords, spatial_dimension, spatial_dimension, false, _ek_regular, true);
model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
Vector<Real> center(spatial_dimension, 0.);
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, _ek_regular);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost, _ek_regular);
Real min_distance = 2;
IntegrationPoint q_min;
for(; it != last_type ; ++it) {
ElementType type = *it;
UInt nb_elements = mesh.getNbElement(type, _not_ghost);
UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(type);
Array<Real> & coords = quad_coords(type, _not_ghost);
Array<Real>::const_vector_iterator coord_it = coords.begin(spatial_dimension);
for (UInt e = 0; e < nb_elements; ++e) {
for (UInt q = 0; q < nb_quads; ++q, ++coord_it) {
Real dist = center.distance(*coord_it);
if (dist < min_distance) {
min_distance = dist;
q_min.element = e;
q_min.num_point = q;
q_min.global_num = nb_elements * nb_quads + q;
q_min.type = type;
}
}
}
}
Real global_min = min_distance;
comm.allReduce(&global_min, 1, _so_min);
if(Math::are_float_equal(global_min, min_distance)) {
UInt mat_index = model.getMaterialByElement(q_min.type, _not_ghost).begin()[q_min.element];
Material & mat = model.getMaterial(mat_index);
UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(q_min.type);
UInt local_el_index = model.getMaterialLocalNumbering(q_min.type, _not_ghost).begin()[q_min.element];
UInt local_num = (local_el_index * nb_quads) + q_min.num_point;
Array<Real> & grad_u = const_cast<Array<Real> &> (mat.getInternal<Real>("grad_u")(q_min.type, _not_ghost));
Array<Real>::iterator< Matrix<Real> > grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
grad_u_it += local_num;
Matrix<Real> & g_u = *grad_u_it;
g_u += applied_strain;
}
/// compute the non-local strains
model.getNonLocalManager().computeAllNonLocalStresses();
model.dump();
/// damage the element with higher grad_u completely, so that it is
/// not taken into account for the averaging
if(Math::are_float_equal(global_min, min_distance)) {
UInt mat_index = model.getMaterialByElement(q_min.type, _not_ghost).begin()[q_min.element];
Material & mat = model.getMaterial(mat_index);
UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(q_min.type);
UInt local_el_index = model.getMaterialLocalNumbering(q_min.type, _not_ghost).begin()[q_min.element];
UInt local_num = (local_el_index * nb_quads) + q_min.num_point;
Array<Real> & damage = const_cast<Array<Real> &> (mat.getInternal<Real>("damage")(q_min.type, _not_ghost));
Real * dam_ptr = damage.storage();
dam_ptr += local_num;
*dam_ptr = 0.9;
}
/// compute the non-local strains
model.getNonLocalManager().computeAllNonLocalStresses();
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_non_local_toolbox/test_material.cc b/test/test_model/test_non_local_toolbox/test_material.cc
index c73a76737..df021a8a2 100644
--- a/test/test_model/test_non_local_toolbox/test_material.cc
+++ b/test/test_model/test_non_local_toolbox/test_material.cc
@@ -1,122 +1,125 @@
/**
* @file test_material.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Sep 23 17:16:30 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
*
* @brief Implementation of test material for the non-local neighborhood base test
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_material.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt dim>
TestMaterial<dim>::TestMaterial(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
MyLocalParent(model, id),
MyNonLocalParent(model, id),
grad_u_nl("grad_u non local", *this) {
this->is_non_local = true;
this->grad_u_nl.initialize(dim*dim);
this->model->getNonLocalManager().registerNonLocalVariable(this->gradu.getName(), grad_u_nl.getName(), dim*dim);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void TestMaterial<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
this->registerNeighborhood();
MyLocalParent::initMaterial();
MyNonLocalParent::initMaterial();
this->model->getNonLocalManager().nonLocalVariableToNeighborhood(grad_u_nl.getName(), "test_region");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void TestMaterial<spatial_dimension>::insertQuadsInNeighborhoods(GhostType ghost_type) {
/// this function will add all the quadrature points to the same
/// default neighborhood instead of using one neighborhood per
/// material
NonLocalManager & manager = this->model->getNonLocalManager();
InternalField<Real> quadrature_points_coordinates("quadrature_points_coordinates_tmp_nl", *this);
quadrature_points_coordinates.initialize(spatial_dimension);
/// intialize quadrature point object
IntegrationPoint q;
q.ghost_type = ghost_type;
q.kind = _ek_regular;
Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_regular);
Mesh::type_iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_regular);
for(; it != last_type; ++it) {
q.type = *it;
const Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if(nb_element) {
UInt nb_quad = this->fem->getNbIntegrationPoints(*it, ghost_type);
UInt nb_tot_quad = nb_quad * nb_element;
Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
quads.resize(nb_tot_quad);
this->model->getFEEngine().computeIntegrationPointsCoordinates(quads, *it, ghost_type, elem_filter);
Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
UInt * elem = elem_filter.storage();
for (UInt e = 0; e < nb_element; ++e) {
q.element = *elem;
for (UInt nq = 0; nq < nb_quad; ++nq) {
q.num_point = nq;
q.global_num = q.element * nb_quad + nq;
manager.insertQuad(q, *quad, "test_region");
++quad;
}
++elem;
}
}
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void TestMaterial<spatial_dimension>::registerNeighborhood() {
this->model->getNonLocalManager().registerNeighborhood("test_region", "test_region");
}
/* -------------------------------------------------------------------------- */
// Instantiate the material for the 3 dimensions
INSTANTIATE_MATERIAL(TestMaterial);
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/test/test_model/test_non_local_toolbox/test_material.hh b/test/test_model/test_non_local_toolbox/test_material.hh
index b8785f23e..04d3fa9b9 100644
--- a/test/test_model/test_non_local_toolbox/test_material.hh
+++ b/test/test_model/test_non_local_toolbox/test_material.hh
@@ -1,75 +1,78 @@
/**
* @file test_material.hh
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Sep 23 17:16:30 2015
+ *
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Wed Nov 25 2015
*
* @brief test material for the non-local neighborhood base test
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_damage.hh"
#include "material_non_local.hh"
#ifndef __TEST_MATERIAL_HH__
#define __TEST_MATERIAL_HH__
__BEGIN_AKANTU__
template<UInt dim>
class TestMaterial : public MaterialDamage<dim, MaterialElastic>,
public MaterialNonLocal<dim>{
/* -------------------------------------------------------------------------- */
/* Constructor/Destructor */
/* -------------------------------------------------------------------------- */
public:
TestMaterial(SolidMechanicsModel & model, const ID & id);
virtual ~TestMaterial() {};
typedef MaterialNonLocal<dim> MyNonLocalParent;
typedef MaterialDamage<dim, MaterialElastic> MyLocalParent;
/* -------------------------------------------------------------------------- */
/* Methods */
/* -------------------------------------------------------------------------- */
public:
void initMaterial();
void computeNonLocalStresses(GhostType ghost_type) {};
void insertQuadsInNeighborhoods(GhostType ghost_type);
virtual void registerNeighborhood();
protected:
/* -------------------------------------------------------------------------- */
/* Members */
/* -------------------------------------------------------------------------- */
private:
InternalField<Real> grad_u_nl;
};
__END_AKANTU__
#endif /* __TEST_MATERIAL_HH__ */
diff --git a/test/test_model/test_non_local_toolbox/test_material_damage.cc b/test/test_model/test_non_local_toolbox/test_material_damage.cc
index a527bfd89..b61c974c8 100644
--- a/test/test_model/test_non_local_toolbox/test_material_damage.cc
+++ b/test/test_model/test_non_local_toolbox/test_material_damage.cc
@@ -1,113 +1,116 @@
/**
- * @file test_material.cc
+ * @file test_material_damage.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Sep 23 17:16:30 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Thu Oct 15 2015
*
* @brief Implementation of test material damage
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_material_damage.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt dim>
TestMaterialDamage<dim>::TestMaterialDamage(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
MaterialDamage<dim>(model, id),
MyNonLocalParent(model, id),
grad_u_nl("grad_u non local", *this) {
this->is_non_local = true;
this->grad_u_nl.initialize(dim*dim);
this->model->getNonLocalManager().registerNonLocalVariable(this->gradu.getName(), grad_u_nl.getName(), dim*dim);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void TestMaterialDamage<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialDamage<spatial_dimension>::initMaterial();
MyNonLocalParent::initMaterial();
this->model->getNonLocalManager().nonLocalVariableToNeighborhood(grad_u_nl.getName(), this->name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void TestMaterialDamage<spatial_dimension>::insertQuadsInNeighborhoods(GhostType ghost_type) {
/// this function will add all the quadrature points to the same
/// default neighborhood instead of using one neighborhood per
/// material
NonLocalManager & manager = this->model->getNonLocalManager();
InternalField<Real> quadrature_points_coordinates("quadrature_points_coordinates_tmp_nl", *this);
quadrature_points_coordinates.initialize(spatial_dimension);
/// intialize quadrature point object
IntegrationPoint q;
q.ghost_type = ghost_type;
q.kind = _ek_regular;
Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_regular);
Mesh::type_iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_regular);
for(; it != last_type; ++it) {
q.type = *it;
const Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if(nb_element) {
UInt nb_quad = this->fem->getNbIntegrationPoints(*it, ghost_type);
UInt nb_tot_quad = nb_quad * nb_element;
Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
quads.resize(nb_tot_quad);
this->model->getFEEngine().computeIntegrationPointsCoordinates(quads, *it, ghost_type, elem_filter);
Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
UInt * elem = elem_filter.storage();
for (UInt e = 0; e < nb_element; ++e) {
q.element = *elem;
for (UInt nq = 0; nq < nb_quad; ++nq) {
q.num_point = nq;
q.global_num = q.element * nb_quad + nq;
manager.insertQuad(q, *quad, this->name);
++quad;
}
++elem;
}
}
}
}
/* -------------------------------------------------------------------------- */
// Instantiate the material for the 3 dimensions
INSTANTIATE_MATERIAL(TestMaterialDamage);
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/test/test_model/test_non_local_toolbox/test_material_damage.hh b/test/test_model/test_non_local_toolbox/test_material_damage.hh
index 3e60157c5..2cec37f8d 100644
--- a/test/test_model/test_non_local_toolbox/test_material_damage.hh
+++ b/test/test_model/test_non_local_toolbox/test_material_damage.hh
@@ -1,76 +1,79 @@
/**
* @file test_material_damage.hh
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Sep 23 17:16:30 2015
+ *
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Thu Oct 15 2015
*
* @brief test material damage for the non-local remove damage test
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_damage.hh"
#include "material_non_local.hh"
#ifndef __TEST_MATERIAL_DAMAGE_HH__
#define __TEST_MATERIAL_DAMAGE_HH__
__BEGIN_AKANTU__
template<UInt dim>
class TestMaterialDamage : public MaterialDamage<dim, MaterialElastic>,
public MaterialNonLocal<dim> {
/* -------------------------------------------------------------------------- */
/* Constructor/Destructor */
/* -------------------------------------------------------------------------- */
public:
TestMaterialDamage(SolidMechanicsModel & model, const ID & id);
virtual ~TestMaterialDamage() {};
typedef MaterialNonLocal<dim> MyNonLocalParent;
/* -------------------------------------------------------------------------- */
/* Methods */
/* -------------------------------------------------------------------------- */
public:
void initMaterial();
//void computeNonLocalStress(ElementType type, GhostType ghost_type = _not_ghost);
void computeNonLocalStresses(GhostType ghost_type) {};
void insertQuadsInNeighborhoods(GhostType ghost_type);
protected:
/* -------------------------------------------------------------------------- */
/* Members */
/* -------------------------------------------------------------------------- */
private:
InternalField<Real> grad_u_nl;
};
__END_AKANTU__
#endif /* __TEST_MATERIAL_DAMAGE_HH__ */
diff --git a/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc b/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
index ac28176bb..34a420635 100644
--- a/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
+++ b/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
@@ -1,109 +1,112 @@
/**
- * @file test_weight_computation.cc
+ * @file test_non_local_averaging.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Sep 23 16:30:12 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Oct 07 2015
*
* @brief test for non-local averaging of strain
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "test_material.hh"
#include "non_local_manager.hh"
#include "non_local_neighborhood.hh"
#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize("material.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
ElementType element_type = _quadrangle_4;
GhostType ghost_type = _not_ghost;
// mesh creation and read
Mesh mesh(spatial_dimension);
mesh.read("plate.msh");
/// model creation
SolidMechanicsModel model(mesh);
/// creation of material selector
MeshDataMaterialSelector<std::string> * mat_selector;
mat_selector = new MeshDataMaterialSelector<std::string>("physical_names", model);
model.setMaterialSelector(*mat_selector);
/// model initialization changed to use our material
model.initFull(SolidMechanicsModelOptions(_static, true));
model.registerNewCustomMaterials< TestMaterial<spatial_dimension> >("test_material");
model.initMaterials();
/// dump material index in paraview
model.addDumpField("material_index");
model.addDumpField("grad_u");
model.addDumpField("grad_u non local");
model.dump();
/// apply constant strain field everywhere in the plate
Matrix<Real> applied_strain(spatial_dimension, spatial_dimension);
applied_strain.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
applied_strain(i,i) = 2.;
/// apply constant grad_u field in all elements
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
Material & mat = model.getMaterial(m);
Array<Real> & grad_u = const_cast<Array<Real> &> (mat.getInternal<Real>("grad_u")(element_type, ghost_type));
Array<Real>::iterator< Matrix<Real> > grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
Array<Real>::iterator< Matrix<Real> > grad_u_end = grad_u.end(spatial_dimension, spatial_dimension);
for (; grad_u_it != grad_u_end; ++grad_u_it)
(*grad_u_it) += applied_strain;
}
/// compute the non-local strains
model.getNonLocalManager().computeAllNonLocalStresses();
model.dump();
/// verify the result: non-local averaging over constant field must
/// yield same constant field
Real test_result = 0.;
Matrix<Real> difference(spatial_dimension, spatial_dimension, 0.);
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
MaterialNonLocal<spatial_dimension> & mat = dynamic_cast<MaterialNonLocal<spatial_dimension> & >(model.getMaterial(m));
Array<Real> & grad_u_nl = const_cast<Array<Real> &> (mat.getInternal<Real>("grad_u non local")(element_type, ghost_type));
Array<Real>::iterator< Matrix<Real> > grad_u_nl_it = grad_u_nl.begin(spatial_dimension, spatial_dimension);
Array<Real>::iterator< Matrix<Real> > grad_u_nl_end = grad_u_nl.end(spatial_dimension, spatial_dimension);
for (; grad_u_nl_it != grad_u_nl_end; ++grad_u_nl_it) {
difference = (*grad_u_nl_it) - applied_strain;
test_result += difference.norm<L_2>();
}
}
if (test_result > 10.e-13) {
std::cout << "the total norm is: " << test_result << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_non_local_toolbox/test_non_local_neighborhood_base.cc b/test/test_model/test_non_local_toolbox/test_non_local_neighborhood_base.cc
index 7a33c6db5..ee7fba659 100644
--- a/test/test_model/test_non_local_toolbox/test_non_local_neighborhood_base.cc
+++ b/test/test_model/test_non_local_toolbox/test_non_local_neighborhood_base.cc
@@ -1,86 +1,89 @@
/**
* @file test_non_local_neighborhood_base.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Sep 23 16:30:12 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Oct 07 2015
*
* @brief test for the class NonLocalNeighborhoodBase
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "test_material.hh"
#include "non_local_neighborhood_base.hh"
#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize("material.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
// mesh creation and read
Mesh mesh(spatial_dimension);
mesh.read("plate.msh");
/// model creation
SolidMechanicsModel model(mesh);
/// creation of material selector
MeshDataMaterialSelector<std::string> * mat_selector;
mat_selector = new MeshDataMaterialSelector<std::string>("physical_names", model);
model.setMaterialSelector(*mat_selector);
/// model initialization changed to use our material
model.initFull(SolidMechanicsModelOptions(_static, true));
model.registerNewCustomMaterials< TestMaterial<spatial_dimension> >("test_material");
model.initMaterials();
/// dump material index in paraview
model.addDumpField("material_index");
model.dump();
NonLocalNeighborhoodBase & neighborhood = model.getNonLocalManager().getNeighborhood("test_region");
/// save the pair of quadrature points and the coords of all neighbors
std::string output_1 = "quadrature_pairs";
std::string output_2 = "neighborhoods";
neighborhood.savePairs(output_1);
neighborhood.saveNeighborCoords(output_2);
/// print results to screen for validation
std::ifstream quad_pairs;
quad_pairs.open("quadrature_pairs.0");
std::string current_line;
while(getline(quad_pairs, current_line))
std::cout << current_line << std::endl;
quad_pairs.close();
std::ifstream neighborhoods;
neighborhoods.open("neighborhoods.0");
while(getline(neighborhoods, current_line))
std::cout << current_line << std::endl;
neighborhoods.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_non_local_toolbox/test_pair_computation.cc b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
index f8b955f44..72b7b04b9 100644
--- a/test/test_model/test_non_local_toolbox/test_pair_computation.cc
+++ b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
@@ -1,216 +1,218 @@
/**
* @file test_pair_computation.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Tue Nov 24 10:33:55 2015
+ *
+ * @date creation: Wed Nov 25 2015
*
* @brief test the weight computation with and without grid
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "test_material_damage.hh"
#include "non_local_manager.hh"
#include "non_local_neighborhood.hh"
#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef std::vector< std::pair<IntegrationPoint, IntegrationPoint> > PairList;
/* -------------------------------------------------------------------------- */
void computePairs(SolidMechanicsModel & model, PairList * pair_list);
int main(int argc, char *argv[]) {
akantu::initialize("material_remove_damage.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
// mesh creation and read
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
if(prank == 0) {
mesh.read("pair_test.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModel model(mesh);
model.initParallel(partition);
delete partition;
/// creation of material selector
MeshDataMaterialSelector<std::string> * mat_selector;
mat_selector = new MeshDataMaterialSelector<std::string>("physical_names", model);
model.setMaterialSelector(*mat_selector);
/// model initialization changed to use our material
model.initFull(SolidMechanicsModelOptions(_static, true));
model.registerNewCustomMaterials< TestMaterialDamage<spatial_dimension> >("test_material");
model.initMaterials();
/// dump material index in paraview
model.addDumpField("material_index");
model.dump();
/// compute the pairs by looping over all the quadrature points
PairList pair_list[2];
computePairs(model, pair_list);
NonLocalManager & manager = model.getNonLocalManager();
const PairList * pairs_mat_1 = manager.getNeighborhood("mat_1").getPairLists();
const PairList * pairs_mat_2 = manager.getNeighborhood("mat_2").getPairLists();
/// compare the number of pairs
UInt nb_not_ghost_pairs_grid = pairs_mat_1[0].size() + pairs_mat_2[0].size();
UInt nb_ghost_pairs_grid = pairs_mat_1[1].size() + pairs_mat_2[1].size();
UInt nb_not_ghost_pairs_no_grid = pair_list[0].size();
UInt nb_ghost_pairs_no_grid = pair_list[1].size();
if ((nb_not_ghost_pairs_grid != nb_not_ghost_pairs_no_grid) ||
(nb_ghost_pairs_grid != nb_ghost_pairs_no_grid)) {
std::cout << "The number of pairs is not correct: TEST FAILED!!!" << std::endl;
finalize();
return EXIT_FAILURE;
}
for (UInt i = 0; i < pairs_mat_1[0].size(); ++i) {
std::pair<IntegrationPoint,IntegrationPoint> p = (pairs_mat_1[0])[i];
PairList::const_iterator it = std::find(pair_list[0].begin(), pair_list[0].end(), (pairs_mat_1[0])[i]);
if(it == pair_list[0].end()) {
std::cout << "The pairs are not correct" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
for (UInt i = 0; i < pairs_mat_2[0].size(); ++i) {
std::pair<IntegrationPoint,IntegrationPoint> p = (pairs_mat_2[0])[i];
PairList::const_iterator it = std::find(pair_list[0].begin(), pair_list[0].end(), (pairs_mat_2[0])[i]);
if(it == pair_list[0].end()) {
std::cout << "The pairs are not correct" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
for (UInt i = 0; i < pairs_mat_1[1].size(); ++i) {
std::pair<IntegrationPoint,IntegrationPoint> p = (pairs_mat_1[1])[i];
PairList::const_iterator it = std::find(pair_list[1].begin(), pair_list[1].end(), (pairs_mat_1[1])[i]);
if(it == pair_list[1].end()) {
std::cout << "The pairs are not correct" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
for (UInt i = 0; i < pairs_mat_2[1].size(); ++i) {
std::pair<IntegrationPoint,IntegrationPoint> p = (pairs_mat_2[1])[i];
PairList::const_iterator it = std::find(pair_list[1].begin(), pair_list[1].end(), (pairs_mat_2[1])[i]);
if(it == pair_list[1].end()) {
std::cout << "The pairs are not correct" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
void computePairs(SolidMechanicsModel & model, PairList * pair_list) {
ElementKind kind = _ek_regular;
Mesh & mesh = model.getMesh();
UInt spatial_dimension = model.getSpatialDimension();
/// compute the quadrature points
ElementTypeMapReal quad_coords("quad_coords");
mesh.initElementTypeMapArray(quad_coords, spatial_dimension, spatial_dimension, false, _ek_regular, true);
model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
/// loop in a n^2 way over all the quads to generate the pairs
Real neighborhood_radius = 0.5;
Mesh::type_iterator it_1 = mesh.firstType(spatial_dimension, _not_ghost, kind);
Mesh::type_iterator last_type_1 = mesh.lastType(spatial_dimension, _not_ghost, kind);
IntegrationPoint q1;
IntegrationPoint q2;
q1.kind = kind;
q2.kind = kind;
GhostType ghost_type_1 = _not_ghost;
q1.ghost_type = ghost_type_1;
Vector<Real> q1_coords(spatial_dimension);
Vector<Real> q2_coords(spatial_dimension);
for(; it_1 != last_type_1 ; ++it_1) {
ElementType type_1 = *it_1;
q1.type = type_1;
UInt nb_elements_1 = mesh.getNbElement(type_1, ghost_type_1);
UInt nb_quads_1 = model.getFEEngine().getNbIntegrationPoints(type_1);
Array<Real> & quad_coords_1 = quad_coords(q1.type, q1.ghost_type);
Array<Real>::const_vector_iterator coord_it_1 = quad_coords_1.begin(spatial_dimension);
for (UInt e_1 = 0; e_1 < nb_elements_1; ++e_1) {
q1.element = e_1;
UInt mat_index_1 = model.getMaterialByElement(q1.type, q1.ghost_type).begin()[q1.element];
for (UInt q_1 = 0; q_1 < nb_quads_1; ++q_1) {
q1.global_num = nb_quads_1 * e_1 + q_1;
q1.num_point = q_1;
q1_coords = coord_it_1[q1.global_num];
/// loop over all other quads and create pairs for this given quad
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type_2 = *gt;
q2.ghost_type = ghost_type_2;
Mesh::type_iterator it_2 = mesh.firstType(spatial_dimension, ghost_type_2, kind);
Mesh::type_iterator last_type_2 = mesh.lastType(spatial_dimension, ghost_type_2, kind);
for(; it_2 != last_type_2 ; ++it_2) {
ElementType type_2 = *it_2;
q2.type = type_2;
UInt nb_elements_2 = mesh.getNbElement(type_2, ghost_type_2);
UInt nb_quads_2 = model.getFEEngine().getNbIntegrationPoints(type_2);
Array<Real> & quad_coords_2 = quad_coords(q2.type, q2.ghost_type);
Array<Real>::const_vector_iterator coord_it_2 = quad_coords_2.begin(spatial_dimension);
for (UInt e_2 = 0; e_2 < nb_elements_2; ++e_2) {
q2.element = e_2;
UInt mat_index_2 = model.getMaterialByElement(q2.type, q2.ghost_type).begin()[q2.element];
for (UInt q_2 = 0; q_2 < nb_quads_2; ++q_2) {
q2.global_num = nb_quads_2 * e_2 + q_2;
q2.num_point = q_2;
q2_coords = coord_it_2[q2.global_num];
Real distance = q1_coords.distance(q2_coords);
if (mat_index_1 != mat_index_2)
continue;
else if(distance <= neighborhood_radius + Math::getTolerance() &&
(q2.ghost_type == _ghost ||
(q2.ghost_type == _not_ghost && q1.global_num <= q2.global_num))) { // storing only half lists
pair_list[q2.ghost_type].push_back(std::make_pair(q1, q2));
}
}
}
}
}
}
}
}
}
diff --git a/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc b/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc
index a342c6adf..c033a2934 100644
--- a/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc
+++ b/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc
@@ -1,179 +1,181 @@
/**
- * @file test_remove_damage_weight_function.cc
- * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Tue Oct 6 14:32:43 2015
- *
- * @brief test the weight function that ignores fully damaged elements
- *
- * @section LICENSE
- *
- * Copyright (©) 2010-2011 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/>.
- *
- */
+ * @file test_remove_damage_weight_function.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Wed Oct 07 2015
+ *
+ * @brief Test the damage weight funcion for non local 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 <http://www.gnu.org/licenses/>.
+ *
+ */
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "test_material_damage.hh"
#include "non_local_manager.hh"
#include "non_local_neighborhood.hh"
#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize("material_remove_damage.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
ElementType element_type = _quadrangle_4;
GhostType ghost_type = _not_ghost;
// mesh creation and read
Mesh mesh(spatial_dimension);
mesh.read("plate.msh");
/// model creation
SolidMechanicsModel model(mesh);
/// creation of material selector
MeshDataMaterialSelector<std::string> * mat_selector;
mat_selector = new MeshDataMaterialSelector<std::string>("physical_names", model);
model.setMaterialSelector(*mat_selector);
/// model initialization changed to use our material
model.initFull(SolidMechanicsModelOptions(_static, true));
model.registerNewCustomMaterials< TestMaterialDamage<spatial_dimension> >("test_material");
model.initMaterials();
/// dump material index in paraview
model.addDumpField("material_index");
model.addDumpField("grad_u");
model.addDumpField("grad_u non local");
model.addDumpField("damage");
model.dump();
/// apply constant strain field in all elements except element 3 and 15
Matrix<Real> applied_strain(spatial_dimension, spatial_dimension);
applied_strain.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
applied_strain(i,i) = 2.;
/// apply different strain in element 3 and 15
Matrix<Real> modified_strain(spatial_dimension, spatial_dimension);
modified_strain.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
modified_strain(i,i) = 1.;
/// apply constant grad_u field in all elements
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
Material & mat = model.getMaterial(m);
Array<Real> & grad_u = const_cast<Array<Real> &> (mat.getInternal<Real>("grad_u")(element_type, ghost_type));
Array<Real>::iterator< Matrix<Real> > grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
Array<Real>::iterator< Matrix<Real> > grad_u_end = grad_u.end(spatial_dimension, spatial_dimension);
UInt element_counter = 0;
for (; grad_u_it != grad_u_end; ++grad_u_it, ++element_counter)
if (element_counter == 12 || element_counter == 13 || element_counter == 14 || element_counter == 15)
(*grad_u_it) += modified_strain;
else
(*grad_u_it) += applied_strain;
}
/// compute the non-local strains
model.getNonLocalManager().computeAllNonLocalStresses();
model.dump();
/// save the weights in a file
NonLocalNeighborhood<RemoveDamagedWeightFunction> & neighborhood_1 = dynamic_cast<NonLocalNeighborhood<RemoveDamagedWeightFunction> &> (model.getNonLocalManager().getNeighborhood("mat_1"));
NonLocalNeighborhood<RemoveDamagedWeightFunction> & neighborhood_2 = dynamic_cast<NonLocalNeighborhood<RemoveDamagedWeightFunction> &> (model.getNonLocalManager().getNeighborhood("mat_2"));
neighborhood_1.saveWeights("before_0");
neighborhood_2.saveWeights("before_1");
for(UInt n = 0; n < 2; ++n) {
/// print results to screen for validation
std::stringstream sstr;
sstr << "before_" << n << ".0";
std::ifstream weights;
weights.open(sstr.str());
std::string current_line;
while(getline(weights, current_line))
std::cout << current_line << std::endl;
weights.close();
}
/// apply damage to not have the elements with lower strain impact the averaging
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
MaterialDamage<spatial_dimension> & mat = dynamic_cast<MaterialDamage<spatial_dimension> & >(model.getMaterial(m));
Array<Real> & damage = const_cast<Array<Real> &> (mat.getInternal<Real>("damage")(element_type, ghost_type));
Array<Real>::scalar_iterator dam_it = damage.begin();
Array<Real>::scalar_iterator dam_end = damage.end();
UInt element_counter = 0;
for (; dam_it != dam_end; ++dam_it, ++element_counter)
if (element_counter == 12 || element_counter == 13 || element_counter == 14 || element_counter == 15)
*dam_it = 0.9;
}
/// compute the non-local strains
model.getNonLocalManager().computeAllNonLocalStresses();
neighborhood_1.saveWeights("after_0");
neighborhood_2.saveWeights("after_1");
for(UInt n = 0; n < 2; ++n) {
/// print results to screen for validation
std::stringstream sstr;
sstr << "after_" << n << ".0";
std::ifstream weights;
weights.open(sstr.str());
std::string current_line;
while(getline(weights, current_line))
std::cout << current_line << std::endl;
weights.close();
}
model.dump();
/// verify the result: non-local averaging over constant field must
/// yield same constant field
Real test_result = 0.;
Matrix<Real> difference(spatial_dimension, spatial_dimension, 0.);
Matrix<Real> difference_in_damaged_elements(spatial_dimension, spatial_dimension, 0.);
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
difference_in_damaged_elements.clear();
MaterialNonLocal<spatial_dimension> & mat = dynamic_cast<MaterialNonLocal<spatial_dimension> & >(model.getMaterial(m));
Array<Real> & grad_u_nl = const_cast<Array<Real> &> (mat.getInternal<Real>("grad_u non local")(element_type, ghost_type));
Array<Real>::iterator< Matrix<Real> > grad_u_nl_it = grad_u_nl.begin(spatial_dimension, spatial_dimension);
Array<Real>::iterator< Matrix<Real> > grad_u_nl_end = grad_u_nl.end(spatial_dimension, spatial_dimension);
UInt element_counter = 0;
for (; grad_u_nl_it != grad_u_nl_end; ++grad_u_nl_it, ++element_counter) {
if (element_counter == 12 || element_counter == 13 || element_counter == 14 || element_counter == 15)
difference_in_damaged_elements += (*grad_u_nl_it);
else
difference = (*grad_u_nl_it) - applied_strain;
test_result += difference.norm<L_2>();
}
difference_in_damaged_elements *= (1/4.);
difference_in_damaged_elements -= (1.41142 *modified_strain);
test_result += difference_in_damaged_elements.norm<L_2>();
}
if (test_result > 10.e-5) {
std::cout << "the total norm is: " << test_result << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_non_local_toolbox/test_weight_computation.cc b/test/test_model/test_non_local_toolbox/test_weight_computation.cc
index 95fd780f0..4df5771b2 100644
--- a/test/test_model/test_non_local_toolbox/test_weight_computation.cc
+++ b/test/test_model/test_non_local_toolbox/test_weight_computation.cc
@@ -1,72 +1,75 @@
/**
* @file test_weight_computation.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Sep 23 16:30:12 2015
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Oct 07 2015
*
* @brief test for the weight computation with base weight function
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "test_material.hh"
#include "non_local_manager.hh"
#include "non_local_neighborhood.hh"
#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize("material_weight_computation.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
// mesh creation and read
Mesh mesh(spatial_dimension);
mesh.read("plate.msh");
/// model creation
SolidMechanicsModel model(mesh);
/// model initialization changed to use our material
model.initFull(SolidMechanicsModelOptions(_static, true));
model.registerNewCustomMaterials< TestMaterial<spatial_dimension> >("test_material");
model.initMaterials();
/// dump material index in paraview
model.addDumpField("material_index");
model.dump();
/// save the weights in a file
NonLocalNeighborhood<BaseWeightFunction> & neighborhood = dynamic_cast<NonLocalNeighborhood<BaseWeightFunction> &> (model.getNonLocalManager().getNeighborhood("test_region"));
neighborhood.saveWeights("weights");
/// print results to screen for validation
std::ifstream weights;
weights.open("weights.0");
std::string current_line;
while(getline(weights, current_line))
std::cout << current_line << std::endl;
weights.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/CMakeLists.txt
index afd8b09d7..3e91dd8af 100644
--- a/test/test_model/test_solid_mechanics_model/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/CMakeLists.txt
@@ -1,221 +1,222 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Fri Sep 03 2010
-# @date last modification: Thu Mar 27 2014
+# @date last modification: Mon Dec 07 2015
#
# @brief configuratio for SolidMechanicsModel tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_solid_mechanics_model_square_mesh square.geo 2 1)
add_mesh(test_solid_mechanics_model_circle_mesh1 circle.geo 2 1 OUTPUT circle1.msh)
add_mesh(test_solid_mechanics_model_circle_mesh2 circle.geo 2 2 OUTPUT circle2.msh)
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
)
#===============================================================================
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
)
#===============================================================================
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.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE implicit
)
#===============================================================================
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
)
#===============================================================================
add_mesh(test_pbc_parallel_mesh square_structured.geo 2 1 OUTPUT square_structured.msh)
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
)
#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
FILES_TO_COPY material.dat cube_physical_names.msh
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 implicit
)
#===============================================================================
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
)
#===============================================================================
register_test(test_material_selector
SOURCES test_material_selector.cc
FILES_TO_COPY material_selector.dat material_selector.msh
PACKAGE core
)
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/patch_tests/CMakeLists.txt
index 028cb1798..28f9f60fd 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/CMakeLists.txt
@@ -1,67 +1,68 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author David Simon Kammer <david.kammer@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Apr 20 2011
-# @date last modification: Thu Mar 27 2014
+# @date creation: Fri Oct 22 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for patch tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_weight_hexa_mesh colone_hexa.geo 3 1)
add_mesh(test_weight_tetra_mesh colone_tetra.geo 3 1)
register_test(test_weight
SOURCES colone_weight.cc
DEPENDS test_weight_hexa_mesh test_weight_tetra_mesh
FILES_TO_COPY material_colone.dat
DIRECTORIES_TO_CREATE paraview/test_weight_hexa paraview/test_weight_tetra
PACKAGE core
)
#===============================================================================
set(LIST_TYPES
segment_2
segment_3
tetrahedron_4
tetrahedron_10
hexahedron_8
hexahedron_20
pentahedron_6
pentahedron_15
)
set(LIST_TYPES_2D
triangle_3
triangle_6
quadrangle_4
quadrangle_8
)
add_akantu_test(explicit "Explicit patch tests")
add_akantu_test(implicit "Implicit patch tests")
add_akantu_test(lumped_mass "Test the mass lumping")
\ No newline at end of file
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/colone_weight.cc b/test/test_model/test_solid_mechanics_model/patch_tests/colone_weight.cc
index aa0955831..9ed9e8d76 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/colone_weight.cc
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/colone_weight.cc
@@ -1,166 +1,167 @@
/**
* @file colone_weight.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
*
- * @date creation: Fri Jul 15 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 09 2010
+ * @date last modification: Thu Aug 06 2015
*
* @brief column test
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
// chose if you use hexahedron elements
bool use_hexa = false;
std::stringstream mesh_file;
std::stringstream output;
std::stringstream energy_file;
akantu::ElementType type;
UInt vel_damping_interval;
if (use_hexa) {
type = akantu::_hexahedron_8;
mesh_file << "colone_hexa.msh";
output << "paraview/test_weight_hexa";
energy_file << "energy_hexa.csv";
vel_damping_interval =4;
}
else {
type = akantu::_tetrahedron_4;
mesh_file << "colone_tetra.msh";
output << "paraview/test_weight_tetra";
energy_file << "energy_tetra.csv";
vel_damping_interval = 8;
}
akantu::UInt spatial_dimension = 3;
akantu::UInt max_steps = 2000;
akantu::Real time_factor = 0.8;
akantu::initialize("material_colone.dat", argc, argv);
// akantu::Real epot, ekin;
akantu::Mesh mesh(spatial_dimension);
mesh.read(mesh_file.str().c_str());
akantu::SolidMechanicsModel model(mesh);
akantu::UInt nb_nodes = mesh.getNbNodes();
akantu::UInt nb_element = mesh.getNbElement(type);
std::cout << "Nb nodes : " << nb_nodes << " - nb elements : " << nb_element << std::endl;
/// model initialization
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.assembleMassLumped();
/// boundary conditions
const akantu::Array<Real> & position = model.getFEEngine().getMesh().getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<Real> & force = model.getForce();
const akantu::Array<Real> & mass = model.getMass();
akantu::Real z_min = position(0, 2);
for (unsigned int i = 0; i < nb_nodes; ++i) {
if(position(i, 2) < z_min)
z_min = position(i, 2);
}
akantu::Real eps = 1e-13;
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
if(fabs(position(i, 2) - z_min) <= eps)
boundary(i,2) = true;
else
force(i,2) = -mass(i,0) * 9.81;
}
akantu::Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
model.updateResidual();
model.setBaseName("colonne_weight");
model.addDumpField("displacement");
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("damage" );
model.addDumpField("stress" );
model.addDumpField("strain" );
model.dump();
akantu::Array<Real> & velocity = model.getVelocity();
std::ofstream energy;
energy.open(energy_file.str().c_str());
energy << "id,epot,ekin,tot" << std::endl;
for(akantu::UInt s = 1; s <= max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
akantu::Real epot = model.getEnergy("potential");
akantu::Real ekin = model.getEnergy("kinetic");
energy << s << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
if (s % vel_damping_interval == 0) {
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
velocity(i, 0) *= 0.9;
velocity(i, 1) *= 0.9;
velocity(i, 2) *= 0.9;
}
}
if(s % 1 == 0) model.dump();
if(s % 10 == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/CMakeLists.txt
index a110d27dc..d23173990 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/CMakeLists.txt
@@ -1,67 +1,68 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author David Simon Kammer <david.kammer@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Thu Feb 17 16:05:48 2011
+# @date creation: Fri Oct 22 2010
+# @date last modification: Tue Dec 02 2014
#
# @brief configuration for the explicit patch test
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
-
macro(register_patch_test_anisotropic name )
set(_mat ../data/material_anisotropic.dat)
register_test(patch_test_explicit_anisotropic
SOURCES patch_test_explicit_anisotropic.cc
FILES_TO_COPY ../data/_tetrahedron_4.msh ${_mat}
PACKAGE core
)
endmacro()
register_patch_test_anisotropic("Anisotropic")
macro(register_patch_test name type plane_strain)
if("${plane_strain}" STREQUAL "false")
set(_mat ../data/material_check_stress_plane_stress.dat)
else()
set(_mat ../data/material_check_stress_plane_strain.dat)
endif()
register_test(patch_test_explicit_${name}
SOURCES patch_test_explicit.cc
FILES_TO_COPY ../data/_${type}.msh ${_mat}
COMPILE_OPTIONS "TYPE=_${type};PLANE_STRAIN=${plane_strain}"
PACKAGE core
)
endmacro()
foreach(_type ${LIST_TYPES})
register_patch_test(${_type} ${_type} true)
endforeach()
foreach(_type ${LIST_TYPES_2D})
register_patch_test(plane_strain_${_type} ${_type} true)
register_patch_test(plane_stress_${_type} ${_type} false)
endforeach()
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit.cc b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit.cc
index a9c2b30c1..59e391aac 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit.cc
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit.cc
@@ -1,290 +1,292 @@
/**
* @file patch_test_explicit.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date Thu Feb 17 16:05:48 2011
+ * @date creation: Sat Apr 16 2011
+ * @date last modification: Thu Oct 15 2015
*
* @brief patch test for elastic material in solid mechanics model
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include "solid_mechanics_model.hh"
using namespace akantu;
Real alpha [3][4] = { { 0.01, 0.02, 0.03, 0.04 },
{ 0.05, 0.06, 0.07, 0.08 },
{ 0.09, 0.10, 0.11, 0.12 } };
/* -------------------------------------------------------------------------- */
template<ElementType type, bool plane_strain>
static Matrix<Real> prescribed_strain() {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> strain(spatial_dimension, spatial_dimension);
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
strain(i, j) = alpha[i][j + 1];
}
}
return strain;
}
template<ElementType type, bool is_plane_strain>
static Matrix<Real> prescribed_stress() {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> stress(spatial_dimension, spatial_dimension);
//plane strain in 2d
Matrix<Real> strain(spatial_dimension, spatial_dimension);
Matrix<Real> pstrain; pstrain = prescribed_strain<type, is_plane_strain>();
Real nu = 0.3;
Real E = 2.1e11;
Real trace = 0;
/// symetric part of the strain tensor
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
strain(i,j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
for (UInt i = 0; i < spatial_dimension; ++i) trace += strain(i,i);
if(spatial_dimension == 1) {
stress(0, 0) = E * strain(0, 0);
} else {
if (is_plane_strain) {
Real Ep = E / (1 + nu);
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j) {
stress(i, j) = Ep * strain(i,j);
if(i == j) stress(i, j) += Ep * (nu / (1 - 2*nu)) * trace;
}
} else {
Real Ep = E / (1 + nu);
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j) {
stress(i, j) = Ep * strain(i,j);
if(i == j) stress(i, j) += (nu * E)/(1-(nu*nu)) * trace;
}
}
}
return stress;
}
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
std::string input_file;
if(PLANE_STRAIN)
input_file = "material_check_stress_plane_strain.dat";
else
input_file = "material_check_stress_plane_stress.dat";
initialize(input_file, argc, argv);
debug::setDebugLevel(dblWarning);
UInt dim = ElementClass<TYPE>::getSpatialDimension();
const ElementType element_type = TYPE;
UInt damping_steps = 600000;
UInt damping_interval = 50;
Real damping_ratio = 0.99;
UInt additional_steps = 20000;
UInt max_steps = damping_steps + additional_steps;
/// load mesh
Mesh my_mesh(dim);
std::stringstream filename; filename << TYPE << ".msh";
my_mesh.read(filename.str());
UInt nb_nodes = my_mesh.getNbNodes();
/// declaration of model
SolidMechanicsModel my_model(my_mesh);
/// model initialization
my_model.initFull();
std::cout << my_model.getMaterial(0) << std::endl;
Real time_step = my_model.getStableTimeStep()/100.;
my_model.setTimeStep(time_step);
my_model.assembleMassLumped();
std::cout << "The number of time steps is: " << max_steps << " (" << time_step << "s)" << std::endl;
// boundary conditions
const Array<Real> & coordinates = my_mesh.getNodes();
Array<Real> & displacement = my_model.getDisplacement();
Array<bool> & boundary = my_model.getBlockedDOFs();
MeshUtils::buildFacets(my_mesh);
my_mesh.createBoundaryGroupFromGeometry();
// Loop over (Sub)Boundar(ies) to block the nodes
for(GroupManager::const_element_group_iterator it(my_mesh.element_group_begin());
it != my_mesh.element_group_end(); ++it)
for(ElementGroup::const_node_iterator nodes_it(it->second->node_begin());
nodes_it!= it->second->node_end(); ++nodes_it)
for (UInt i = 0; i < dim; ++i) boundary(*nodes_it, i) = true;
// set the position of all nodes to the static solution
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt i = 0; i < dim; ++i) {
displacement(n, i) = alpha[i][0];
for (UInt j = 0; j < dim; ++j) {
displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
}
}
}
Array<Real> & velocity = my_model.getVelocity();
std::ofstream energy;
std::stringstream energy_filename; energy_filename << "energy_" << TYPE << ".csv";
energy.open(energy_filename.str().c_str());
energy << "id,time,ekin" << std::endl;
Real ekin_mean = 0.;
//#define DEBUG_TEST
#ifdef DEBUG_TEST
my_model.solveStep();
my_model.addDumpField("strain");
my_model.addDumpField("stress");
my_model.addDumpField("residual");
my_model.addDumpField("velocity");
my_model.addDumpField("acceleration");
my_model.addDumpField("displacement");
my_model.dump();
#endif
/* ------------------------------------------------------------------------ */
/* Main loop */
/* ------------------------------------------------------------------------ */
UInt s;
for(s = 1; s <= max_steps; ++s) {
if(s % 10000 == 0) std::cout << "passing step " << s << "/" << max_steps
<< " (" << s*time_step << "s)" <<std::endl;
// damp velocity in order to find equilibrium
if((s < damping_steps) && (s % damping_interval == 0)) {
velocity *= damping_ratio;
}
if(s % 1000 == 0) {
ekin_mean = ekin_mean / 1000.;
std::cout << "Ekin mean = " << ekin_mean << std::endl;
if (ekin_mean < 1e-10) break;
ekin_mean = 0.;
}
my_model.solveStep();
akantu::Real ekin = my_model.getEnergy("kinetic"); ekin_mean += ekin;
if(s % 1000 == 0)
energy << s << "," << s*time_step << "," << ekin << std::endl;
}
energy.close();
UInt nb_quadrature_points = my_model.getFEEngine().getNbIntegrationPoints(TYPE);
Array<Real> & stress_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getStress(element_type));
Array<Real> & strain_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getGradU(element_type));
Array<Real>::matrix_iterator stress_it = stress_vect.begin(dim, dim);
Array<Real>::matrix_iterator strain_it = strain_vect.begin(dim, dim);
Matrix<Real> presc_stress; presc_stress = prescribed_stress<TYPE, PLANE_STRAIN>();
Matrix<Real> presc_strain; presc_strain = prescribed_strain<TYPE, PLANE_STRAIN>();
UInt nb_element = my_mesh.getNbElement(TYPE);
Real strain_tolerance = 1e-13;
Real stress_tolerance = 1e-13;
for (UInt el = 0; el < nb_element; ++el) {
for (UInt q = 0; q < nb_quadrature_points; ++q) {
Matrix<Real> & stress = *stress_it;
Matrix<Real> & strain = *strain_it;
Matrix<Real> diff(dim, dim);
diff = strain;
diff -= presc_strain;
Real strain_error = diff.norm<L_inf>() / strain.norm<L_inf>();
if(strain_error > strain_tolerance) {
std::cerr << "strain error: " << strain_error << " > " << strain_tolerance << std::endl;
std::cerr << "strain: " << strain << std::endl
<< "prescribed strain: " << presc_strain << std::endl;
return EXIT_FAILURE;
} else {
std::cerr << "strain error: " << strain_error << " < " << strain_tolerance << std::endl;
}
diff = stress;
diff -= presc_stress;
Real stress_error = diff.norm<L_inf>() / stress.norm<L_inf>();
if(stress_error > stress_tolerance) {
std::cerr << "stress error: " << stress_error << " > " << stress_tolerance << std::endl;
std::cerr << "stress: " << stress << std::endl
<< "prescribed stress: " << presc_stress << std::endl;
return EXIT_FAILURE;
} else {
std::cerr << "stress error: " << stress_error << " < " << stress_tolerance << std::endl;
}
++stress_it;
++strain_it;
}
}
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt i = 0; i < dim; ++i) {
Real disp = alpha[i][0];
for (UInt j = 0; j < dim; ++j) {
disp += alpha[i][j + 1] * coordinates(n, j);
}
if(!(std::abs(displacement(n,i) - disp) < 1e-7)) {
std::cerr << "displacement(" << n << ", " << i <<")=" << displacement(n,i) << " should be equal to " << disp << "(" << displacement(n,i) - disp << ")" << std::endl;
return EXIT_FAILURE;
}
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit_anisotropic.cc b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit_anisotropic.cc
index 3e63a6c51..e87145442 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit_anisotropic.cc
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit_anisotropic.cc
@@ -1,302 +1,305 @@
/**
- * @file patch_test_explicit.cc
+ * @file patch_test_explicit_anisotropic.cc
*
+ * @author Till Junge <till.junge@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
- * @date Thu Feb 17 16:05:48 2011
+ * @date creation: Sat Apr 16 2011
+ * @date last modification: Thu Oct 15 2015
*
* @brief patch test for elastic material in solid mechanics model
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
#include "solid_mechanics_model.hh"
using namespace akantu;
Real alpha [3][4] = { { 0.01, 0.02, 0.03, 0.04 },
{ 0.05, 0.06, 0.07, 0.08 },
{ 0.09, 0.10, 0.11, 0.12 } };
//Stiffness tensor, rotated by hand
Real C[3][3][3][3] = {{{{112.93753505, 1.85842452538e-10, -4.47654358027e-10},
{1.85847317471e-10, 54.2334345331, -3.69840984824},
{-4.4764768395e-10, -3.69840984824, 56.848605217}},
{{1.85847781609e-10, 25.429294233, -3.69840984816},
{25.429294233, 3.31613847493e-10, -8.38797920011e-11},
{-3.69840984816, -8.38804581349e-11, -1.97875715813e-10}},
{{-4.47654358027e-10, -3.69840984816, 28.044464917},
{-3.69840984816, 2.09374961813e-10, 9.4857455224e-12},
{28.044464917, 9.48308098714e-12, -2.1367885239e-10}}},
{{{1.85847781609e-10, 25.429294233, -3.69840984816},
{25.429294233, 3.31613847493e-10, -8.38793479119e-11},
{-3.69840984816, -8.38795699565e-11, -1.97876381947e-10}},
{{54.2334345331, 3.31617400207e-10, 2.09372075233e-10},
{3.3161562385e-10, 115.552705733, -3.15093728886e-10},
{2.09372075233e-10, -3.15090176173e-10, 54.2334345333}},
{{-3.69840984824, -8.38795699565e-11, 9.48219280872e-12},
{-8.38795699565e-11, -3.1509195253e-10, 25.4292942335},
{9.48441325477e-12, 25.4292942335, 3.69840984851}}},
{{{-4.47653469848e-10, -3.69840984816, 28.044464917},
{-3.69840984816, 2.09374073634e-10, 9.48752187924e-12},
{28.044464917, 9.48552347779e-12, -2.1367885239e-10}},
{{-3.69840984824, -8.3884899027e-11, 9.48219280872e-12},
{-8.3884899027e-11, -3.150972816e-10, 25.4292942335},
{9.48041645188e-12, 25.4292942335, 3.69840984851}},
{{56.848605217, -1.97875493768e-10, -2.13681516925e-10},
{-1.97877270125e-10, 54.2334345333, 3.69840984851},
{-2.13683293282e-10, 3.69840984851, 112.93753505}}}};
/* -------------------------------------------------------------------------- */
template<ElementType type>
static Matrix<Real> prescribed_grad_u() {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
grad_u(i, j) = alpha[i][j + 1];
}
}
return grad_u;
}
template<ElementType type>
static Matrix<Real> prescribed_stress() {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> stress(spatial_dimension, spatial_dimension);
//plane strain in 2d
Matrix<Real> strain(spatial_dimension, spatial_dimension);
Matrix<Real> pstrain; pstrain = prescribed_grad_u<type>();
Real trace = 0;
/// symetric part of the strain tensor
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
strain(i,j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
for (UInt i = 0; i < spatial_dimension; ++i) trace += strain(i,i);
for (UInt i = 0 ; i < spatial_dimension ; ++i) {
for (UInt j = 0 ; j < spatial_dimension ; ++j) {
stress(i, j) = 0;
for (UInt k = 0 ; k < spatial_dimension ; ++k) {
for (UInt l = 0 ; l < spatial_dimension ; ++l) {
stress(i, j) += C[i][j][k][l]*strain(k, l);
}
}
}
}
return stress;
}
#define TYPE _tetrahedron_4
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
initialize("material_anisotropic.dat", argc, argv);
UInt dim = ElementClass<TYPE>::getSpatialDimension();
const ElementType element_type = TYPE;
UInt damping_steps = 600000;
UInt damping_interval = 50;
Real damping_ratio = 0.99;
UInt additional_steps = 20000;
UInt max_steps = damping_steps + additional_steps;
/// load mesh
Mesh my_mesh(dim);
std::stringstream filename; filename << TYPE << ".msh";
my_mesh.read(filename.str());
UInt nb_nodes = my_mesh.getNbNodes();
/// declaration of model
SolidMechanicsModel my_model(my_mesh);
/// model initialization
my_model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass));
std::cout << my_model.getMaterial(0) << std::endl;
Real time_step = my_model.getStableTimeStep()/5.;
my_model.setTimeStep(time_step);
my_model.assembleMassLumped();
std::cout << "The number of time steps is: " << max_steps << " (" << time_step << "s)" << std::endl;
// boundary conditions
const Array<Real> & coordinates = my_mesh.getNodes();
Array<Real> & displacement = my_model.getDisplacement();
Array<bool> & boundary = my_model.getBlockedDOFs();
MeshUtils::buildFacets(my_mesh);
my_mesh.createBoundaryGroupFromGeometry();
// Loop over (Sub)Boundar(ies)
// Loop over (Sub)Boundar(ies)
for(GroupManager::const_element_group_iterator it(my_mesh.element_group_begin());
it != my_mesh.element_group_end(); ++it) {
for(ElementGroup::const_node_iterator nodes_it(it->second->node_begin());
nodes_it!= it->second->node_end(); ++nodes_it) {
UInt n(*nodes_it);
std::cout << "Node " << *nodes_it << std::endl;
for (UInt i = 0; i < dim; ++i) {
displacement(n, i) = alpha[i][0];
for (UInt j = 0; j < dim; ++j) {
displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
}
boundary(n, i) = true;
}
}
}
// Actually, loop over all nodes, since I wanna test a static solution
for (UInt n = 0 ; n < nb_nodes ; ++n) {
for (UInt i = 0 ; i < dim ; ++i) {
displacement(n, i) = alpha[i][0];
for (UInt j = 0 ; j < dim ; ++j) {
displacement(n, i) += alpha[i][j+1] * coordinates(n, j);
}
}
}
Array<Real> & velocity = my_model.getVelocity();
std::ofstream energy;
std::stringstream energy_filename; energy_filename << "energy_" << TYPE << ".csv";
energy.open(energy_filename.str().c_str());
energy << "id,time,ekin" << std::endl;
Real ekin_mean = 0.;
/* ------------------------------------------------------------------------ */
/* Main loop */
/* ------------------------------------------------------------------------ */
UInt s;
for(s = 1; s <= max_steps; ++s) {
if(s % 10000 == 0) std::cout << "passing step " << s << "/" << max_steps
<< " (" << s*time_step << "s)" <<std::endl;
// damp velocity in order to find equilibrium
if((s < damping_steps) && (s % damping_interval == 0)) {
velocity *= damping_ratio;
}
if(s % 1000 == 0) {
ekin_mean = ekin_mean / 1000.;
std::cout << "Ekin mean = " << ekin_mean << std::endl;
if (ekin_mean < 1e-10) break;
ekin_mean = 0.;
}
my_model.explicitPred();
my_model.updateResidual();
my_model.updateAcceleration();
my_model.explicitCorr();
akantu::Real ekin = my_model.getEnergy("kinetic"); ekin_mean += ekin;
if(s % 1000 == 0)
energy << s << "," << s*time_step << "," << ekin << std::endl;
}
energy.close();
UInt nb_quadrature_points = my_model.getFEEngine().getNbIntegrationPoints(TYPE);
Array<Real> & stress_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getStress(element_type));
Array<Real> & gradu_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getGradU(element_type));
Array<Real>::iterator< Matrix<Real> > stress_it = stress_vect.begin(dim, dim);
Array<Real>::iterator< Matrix<Real> > gradu_it = gradu_vect.begin(dim, dim);
Matrix<Real> presc_stress; presc_stress = prescribed_stress<TYPE>();
Matrix<Real> presc_gradu; presc_gradu = prescribed_grad_u<TYPE>();
UInt nb_element = my_mesh.getNbElement(TYPE);
Real gradu_tolerance = 1e-9;
Real stress_tolerance = 1e-2;
if(s > max_steps) {
stress_tolerance = 1e-4;
gradu_tolerance = 1e-7;
}
for (UInt el = 0; el < nb_element; ++el) {
for (UInt q = 0; q < nb_quadrature_points; ++q) {
Matrix<Real> & stress = *stress_it;
Matrix<Real> & gradu = *gradu_it;
for (UInt i = 0; i < dim; ++i) {
for (UInt j = 0; j < dim; ++j) {
if(!(std::abs(gradu(i, j) - presc_gradu(i, j)) < gradu_tolerance)) {
std::cerr << "gradu[" << i << "," << j << "] = " << gradu(i, j) << " but should be = " << presc_gradu(i, j) << " (-" << std::abs(gradu(i, j) - presc_gradu(i, j)) << ") [el : " << el<< " - q : " << q << "]" << std::endl;
std::cerr << gradu << presc_gradu << std::endl;
return EXIT_FAILURE;
}
if(!(std::abs(stress(i, j) - presc_stress(i, j)) < stress_tolerance)) {
std::cerr << "stress[" << i << "," << j << "] = " << stress(i, j) << " but should be = " << presc_stress(i, j) << " (-" << std::abs(stress(i, j) - presc_stress(i, j)) << ") [el : " << el<< " - q : " << q << "]" << std::endl;
std::cerr << stress << presc_stress << std::endl;
return EXIT_FAILURE;
}
}
}
++stress_it;
++gradu_it;
}
}
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt i = 0; i < dim; ++i) {
Real disp = alpha[i][0];
for (UInt j = 0; j < dim; ++j) {
disp += alpha[i][j + 1] * coordinates(n, j);
}
if(!(std::abs(displacement(n,i) - disp) < 1e-7)) {
std::cerr << "displacement(" << n << ", " << i <<")=" << displacement(n,i) << " should be equal to " << disp << "(" << displacement(n,i) - disp << ")" << std::endl;
return EXIT_FAILURE;
}
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/implicit/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/patch_tests/implicit/CMakeLists.txt
index d05c34f5a..7d69cf0aa 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/implicit/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/implicit/CMakeLists.txt
@@ -1,55 +1,56 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author David Simon Kammer <david.kammer@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Feb 17 2011
-# @date last modification: Thu Feb 21 2013
+# @date creation: Fri Oct 22 2010
+# @date last modification: Sun Oct 19 2014
#
# @brief configuration for the implicit patch test
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
macro(register_patch_test name type plane_strain)
if("${plane_strain}" STREQUAL "false")
set(_mat ../data/material_check_stress_plane_stress.dat)
else()
set(_mat ../data/material_check_stress_plane_strain.dat)
endif()
register_test(patch_test_implicit_${name}
SOURCES patch_test_implicit.cc
FILES_TO_COPY ../data/_${type}.msh ${_mat}
COMPILE_OPTIONS "TYPE=_${type};PLANE_STRAIN=${plane_strain}"
PACKAGE implicit
)
endmacro()
foreach(_type ${LIST_TYPES})
register_patch_test(${_type} ${_type} true)
endforeach()
foreach(_type ${LIST_TYPES_2D})
register_patch_test(plane_strain_${_type} ${_type} true)
register_patch_test(plane_stress_${_type} ${_type} false)
endforeach()
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc b/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc
index cc45205cb..02adc87ac 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc
@@ -1,232 +1,233 @@
/**
* @file patch_test_implicit.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Feb 17 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Sat Apr 16 2011
+ * @date last modification: Thu Oct 15 2015
*
* @brief patch test for elastic material in solid mechanics model
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
Real alpha [3][4] = { { 0.01, 0.02, 0.03, 0.04 },
{ 0.05, 0.06, 0.07, 0.08 },
{ 0.09, 0.10, 0.11, 0.12 } };
/* -------------------------------------------------------------------------- */
template<ElementType type, bool is_plane_strain>
static Matrix<Real> prescribed_strain() {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> strain(spatial_dimension, spatial_dimension);
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
strain(i, j) = alpha[i][j + 1];
}
}
return strain;
}
template<ElementType type, bool is_plane_strain>
static Matrix<Real> prescribed_stress() {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> stress(spatial_dimension, spatial_dimension);
//plane strain in 2d
Matrix<Real> strain(spatial_dimension, spatial_dimension);
Matrix<Real> pstrain; pstrain = prescribed_strain<type, is_plane_strain>();
Real nu = 0.3;
Real E = 2.1e11;
Real trace = 0;
/// symetric part of the strain tensor
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
strain(i,j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
for (UInt i = 0; i < spatial_dimension; ++i) trace += strain(i,i);
Real lambda = nu * E / ((1 + nu) * (1 - 2*nu));
Real mu = E / (2 * (1 + nu));
if(!is_plane_strain) {
std::cout << "toto" << std::endl;
lambda = nu * E / (1 - nu*nu);
}
if(spatial_dimension == 1) {
stress(0, 0) = E * strain(0, 0);
} else {
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j) {
stress(i, j) = (i == j)*lambda*trace + 2*mu*strain(i, j);
}
}
return stress;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
std::string input_file;
if(PLANE_STRAIN)
input_file = "material_check_stress_plane_strain.dat";
else
input_file = "material_check_stress_plane_stress.dat";
initialize(input_file, argc, argv);
UInt dim = ElementClass<TYPE>::getSpatialDimension();
const ElementType element_type = TYPE;
/// load mesh
Mesh my_mesh(dim);
std::stringstream filename; filename << TYPE << ".msh";
my_mesh.read(filename.str());
// MeshUtils::purifyMesh(my_mesh);
UInt nb_nodes = my_mesh.getNbNodes();
/// declaration of model
SolidMechanicsModel my_model(my_mesh);
/// model initialization
my_model.initFull(SolidMechanicsModelOptions(_static));
const Array<Real> & coordinates = my_mesh.getNodes();
Array<Real> & displacement = my_model.getDisplacement();
Array<bool> & boundary = my_model.getBlockedDOFs();
MeshUtils::buildFacets(my_mesh);
my_mesh.createBoundaryGroupFromGeometry();
// Loop over (Sub)Boundar(ies)
for(GroupManager::const_element_group_iterator it(my_mesh.element_group_begin());
it != my_mesh.element_group_end(); ++it) {
for(ElementGroup::const_node_iterator nodes_it(it->second->node_begin());
nodes_it!= it->second->node_end(); ++nodes_it) {
UInt n(*nodes_it);
std::cout << "Node " << *nodes_it << std::endl;
for (UInt i = 0; i < dim; ++i) {
displacement(n, i) = alpha[i][0];
for (UInt j = 0; j < dim; ++j) {
displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
}
boundary(n, i) = true;
}
}
}
/* ------------------------------------------------------------------------ */
/* Static solve */
/* ------------------------------------------------------------------------ */
my_model.solveStep<_scm_newton_raphson_tangent_modified, _scc_residual>(2e-4, 2);
my_model.getStiffnessMatrix().saveMatrix("clown_matrix.mtx");
/* ------------------------------------------------------------------------ */
/* Checks */
/* ------------------------------------------------------------------------ */
UInt nb_quadrature_points = my_model.getFEEngine().getNbIntegrationPoints(element_type);
Array<Real> & stress_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getStress(element_type));
Array<Real> & strain_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getGradU(element_type));
Array<Real>::matrix_iterator stress_it = stress_vect.begin(dim, dim);
Array<Real>::matrix_iterator strain_it = strain_vect.begin(dim, dim);
Matrix<Real> presc_stress; presc_stress = prescribed_stress<TYPE, PLANE_STRAIN>();
Matrix<Real> presc_strain; presc_strain = prescribed_strain<TYPE, PLANE_STRAIN>();
UInt nb_element = my_mesh.getNbElement(TYPE);
Real strain_tolerance = 1e-13;
Real stress_tolerance = 1e-13;
for (UInt el = 0; el < nb_element; ++el) {
for (UInt q = 0; q < nb_quadrature_points; ++q) {
Matrix<Real> & stress = *stress_it;
Matrix<Real> & strain = *strain_it;
Matrix<Real> diff(dim, dim);
diff = strain;
diff -= presc_strain;
Real strain_error = diff.norm<L_inf>() / strain.norm<L_inf>();
if(strain_error > strain_tolerance) {
std::cerr << "strain error: " << strain_error << " > " << strain_tolerance << std::endl;
std::cerr << "strain: " << strain << std::endl
<< "prescribed strain: " << presc_strain << std::endl;
return EXIT_FAILURE;
} else {
std::cerr << "strain error: " << strain_error << " < " << strain_tolerance << std::endl;
}
diff = stress;
diff -= presc_stress;
Real stress_error = diff.norm<L_inf>() / stress.norm<L_inf>();
if(stress_error > stress_tolerance) {
std::cerr << "stress error: " << stress_error << " > " << stress_tolerance << std::endl;
std::cerr << "stress: " << stress << std::endl
<< "prescribed stress: " << presc_stress << std::endl;
return EXIT_FAILURE;
} else {
std::cerr << "stress error: " << stress_error << " < " << stress_tolerance << std::endl;
}
++stress_it;
++strain_it;
}
}
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt i = 0; i < dim; ++i) {
Real disp = alpha[i][0];
for (UInt j = 0; j < dim; ++j) {
disp += alpha[i][j + 1] * coordinates(n, j);
}
if(!(std::abs(displacement(n,i) - disp) < 2e-15)) {
std::cerr << "displacement(" << n << ", " << i <<")=" << displacement(n,i) << " should be equal to " << disp << std::endl;
return EXIT_FAILURE;
}
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/lumped_mass/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/patch_tests/lumped_mass/CMakeLists.txt
index f16c1adbf..608939b60 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/lumped_mass/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/lumped_mass/CMakeLists.txt
@@ -1,45 +1,46 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author David Simon Kammer <david.kammer@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Thu Mar 27 2014
-# @date last modification: Thu Mar 27 2014
+# @date creation: Wed Oct 27 2010
+# @date last modification: Sun Oct 19 2014
#
# @brief configuration for the explicit patch test
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
macro(register_patch_test name type)
register_test(test_lumped_mass_${name}
SOURCES test_lumped_mass.cc
FILES_TO_COPY ../data/_${type}.msh ../data/material.dat
COMPILE_OPTIONS "TYPE=_${type}"
PACKAGE core
)
endmacro()
foreach(_type ${LIST_TYPES} ${LIST_TYPES_2D})
register_patch_test(${_type} ${_type})
endforeach()
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/lumped_mass/test_lumped_mass.cc b/test/test_model/test_solid_mechanics_model/patch_tests/lumped_mass/test_lumped_mass.cc
index 374a492e3..77c4d531d 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/lumped_mass/test_lumped_mass.cc
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/lumped_mass/test_lumped_mass.cc
@@ -1,91 +1,91 @@
/**
* @file test_lumped_mass.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Mar 27 2014
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief test the lumping of the mass matrix
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
UInt spatial_dimension = ElementClass<TYPE>::getSpatialDimension();
const ElementType type = TYPE;
akantu::initialize("material.dat", argc, argv);
Mesh mesh(spatial_dimension);
std::stringstream filename; filename << TYPE << ".msh";
mesh.read(filename.str());
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
model.assembleMassLumped();
Real rho = model.getMaterial(0).getRho();
FEEngine & fem = model.getFEEngine();
UInt nb_element = mesh.getNbElement(type);
UInt nb_quadrature_points = fem.getNbIntegrationPoints(type) * nb_element;
Array<Real> rho_on_quad(nb_quadrature_points, 1, rho, "rho_on_quad");
Real mass = fem.integrate(rho_on_quad, type);
Array<Real>::const_vector_iterator mass_it = model.getMass().begin(spatial_dimension);
Array<Real>::const_vector_iterator mass_end = model.getMass().end(spatial_dimension);
Vector<Real> sum(spatial_dimension, 0.);
for(; mass_it != mass_end; ++mass_it) {
sum += *mass_it;
}
std::cout << mass << std::endl << sum << std::endl;
if(!(std::abs((mass - sum[0])/mass) < 2e-15)) {
std::cerr << "total mass is not correct" << std::endl;
return EXIT_FAILURE;
}
for(UInt i = 1; i < spatial_dimension; ++i)
if(!(std::abs((sum[0] - sum[i])/mass) < 1e-15)) {
std::cerr << "total mass is not correct" << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/CMakeLists.txt
index e7d555db3..7dba0beca 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/CMakeLists.txt
@@ -1,40 +1,41 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
-# @date creation: Tue May 08 2012
-# @date last modification: Fri Jun 21 2013
+# @date creation: Fri Oct 22 2010
+# @date last modification: Thu Jan 14 2016
#
# @brief configuration for cohesive elements tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_cohesive_intrinsic "test_cohesive_intrinsic")
add_akantu_test(test_cohesive_extrinsic "test_cohesive_extrinsic")
add_akantu_test(test_cohesive_buildfragments "test_cohesive_buildfragments")
add_akantu_test(test_cohesive_intrinsic_impl "test_cohesive_intrinsic_impl")
add_akantu_test(test_cohesive_1d_element "test_cohesive_1d_element")
add_akantu_test(test_cohesive_extrinsic_implicit "test_cohesive_extrinsic_implicit")
add_akantu_test(test_cohesive_insertion "test_cohesive_insertion")
#===============================================================================
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/CMakeLists.txt
index 685e52498..d8d742034 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/CMakeLists.txt
@@ -1,42 +1,43 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
-# @date creation: Fri Jun 14 2013
-# @date last modification: Fri Jun 14 2013
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for parallel test for extrinsic cohesive elements
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
if(AKANTU_PARALLEL)
add_mesh(test_cohesive_1d_element_mesh bar.geo 1 2)
register_test(test_cohesive_1d_element
SOURCES test_cohesive_1d_element.cc
DEPENDS test_cohesive_1d_element_mesh
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE cohesive_element)
endif()
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc
index dcbacdb6c..ae7186247 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc
@@ -1,133 +1,133 @@
/**
* @file test_cohesive_1d_element.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 14 2013
- * @date last modification: Mon Jun 23 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test for 1D cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
const UInt max_steps = 2000;
const Real strain_rate = 4;
UInt spatial_dimension = 1;
Mesh mesh(spatial_dimension, "mesh");
mesh.read("bar.msh");
SolidMechanicsModelCohesive model(mesh);
model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
Real time_step = model.getStableTimeStep()*0.01;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
mesh.computeBoundingBox();
Real posx_max = mesh.getUpperBounds()(0);
Real posx_min = mesh.getLowerBounds()(0);
/// initial conditions
Array<Real> & velocity = model.getVelocity();
const Array<Real> & position = mesh.getNodes();
UInt nb_nodes = mesh.getNbNodes();
for (UInt n = 0; n < nb_nodes; ++n)
velocity(n) = strain_rate * (position(n) - (posx_max + posx_min) /2.);
/// boundary conditions
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
Real disp_increment = strain_rate * (posx_max - posx_min) / 2. * time_step;
for(UInt node = 0; node < mesh.getNbNodes(); ++node) {
if(Math::are_float_equal(position(node), posx_min)) { // left side
boundary(node) = true;
}
if(Math::are_float_equal(position(node), posx_max)) { // right side
boundary(node) = true;
}
}
model.synchronizeBoundaries();
model.updateResidual();
// model.setBaseName("extrinsic_parallel");
// model.addDumpFieldVector("displacement");
// model.addDumpField("velocity" );
// model.addDumpField("acceleration");
// model.addDumpField("residual" );
// model.addDumpField("stress");
// model.addDumpField("strain");
// model.dump();
for (UInt s = 1; s <= max_steps; ++s) {
model.checkCohesiveStress();
model.solveStep();
UInt nb_cohesive_elements = mesh.getNbElement(_cohesive_1d_2);
if (s % 10 == 0) {
std::cout << "passing step " << s << "/" << max_steps
<< ", number of cohesive elemets:"
<< nb_cohesive_elements << std::endl;
// model.dump();
}
/// update external work and boundary conditions
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if(Math::are_float_equal(position(n), posx_min)) // left side
displacement(n) -= disp_increment;
if(Math::are_float_equal(position(n), posx_max)) // right side
displacement(n) += disp_increment;
}
}
Real Ed = model.getEnergy("dissipated");
Real Edt = 100 * 3;
std::cout << Ed << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
finalize();
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/test_cohesive_buildfragments.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/test_cohesive_buildfragments.cc
index 9f04d1e74..1bc74a0dc 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/test_cohesive_buildfragments.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/test_cohesive_buildfragments.cc
@@ -1,200 +1,202 @@
/**
* @file test_cohesive_buildfragments.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date Wed Jun 13 11:29:49 2012
+ * @date creation: Tue May 08 2012
+ * @date last modification: Thu Oct 15 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive.hh"
#include "fragment_manager.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat",argc, argv);
Math::setTolerance(1e-14);
const UInt spatial_dimension = 2;
const UInt max_steps = 200;
Real strain_rate = 1.e5;
ElementType type = _quadrangle_4;
Real L = 0.03;
Real theoretical_mass = L * L/20. * 2500;
ElementType type_facet = Mesh::getFacetType(type);
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
Mesh mesh(spatial_dimension);
mesh.read("mesh.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
Real time_step = model.getStableTimeStep()*0.05;
model.setTimeStep(time_step);
// std::cout << "Time step: " << time_step << std::endl;
Real disp_increment = strain_rate * L / 2. * time_step;
model.assembleMassLumped();
Array<Real> & velocity = model.getVelocity();
const Array<Real> & position = mesh.getNodes();
UInt nb_nodes = mesh.getNbNodes();
/// initial conditions
for (UInt n = 0; n < nb_nodes; ++n)
velocity(n, 0) = strain_rate * position(n, 0);
/// boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0, _x), "Left_side");
model.applyBC(BC::Dirichlet::FixedValue(0, _x), "Right_side");
model.updateResidual();
model.setBaseName("extrinsic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("residual" );
model.addDumpField("stress");
model.addDumpField("strain");
model.dump();
UInt cohesive_index = 1;
UInt nb_quad_per_facet = model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
MaterialCohesive & mat_cohesive
= dynamic_cast<MaterialCohesive&>(model.getMaterial(cohesive_index));
const Array<Real> & damage = mat_cohesive.getDamage(type_cohesive);
FragmentManager fragment_manager(model, false);
const Array<Real> & fragment_mass = fragment_manager.getMass();
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
model.checkCohesiveStress();
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
/// apply boundary conditions
model.applyBC(BC::Dirichlet::IncrementValue(-disp_increment, _x), "Left_side");
model.applyBC(BC::Dirichlet::IncrementValue( disp_increment, _x), "Right_side");
if(s % 1 == 0) {
// model.dump();
std::cout << "passing step " << s << "/" << max_steps << std::endl;
fragment_manager.computeAllData();
/// check number of fragments
UInt nb_fragment_num = fragment_manager.getNbFragment();
UInt nb_cohesive_elements = mesh.getNbElement(type_cohesive);
UInt nb_fragment = 1;
for (UInt el = 0; el < nb_cohesive_elements; ++el) {
UInt q = 0;
while (q < nb_quad_per_facet &&
Math::are_float_equal(damage(el*nb_quad_per_facet + q), 1)) ++q;
if (q == nb_quad_per_facet) {
++nb_fragment;
}
}
if (nb_fragment != nb_fragment_num) {
std::cout << "The number of fragments is wrong!" << std::endl;
return EXIT_FAILURE;
}
/// check mass computation
Real total_mass = 0.;
for (UInt frag = 0; frag < nb_fragment_num; ++frag) {
total_mass += fragment_mass(frag);
}
if (!Math::are_float_equal(theoretical_mass, total_mass)) {
std::cout << "The fragments' mass is wrong!" << std::endl;
return EXIT_FAILURE;
}
}
}
model.dump();
/// check velocities
UInt nb_fragment = fragment_manager.getNbFragment();
const Array<Real> & fragment_velocity = fragment_manager.getVelocity();
const Array<Real> & fragment_center = fragment_manager.getCenterOfMass();
Real fragment_length = L / nb_fragment;
Real initial_position = -L / 2. + fragment_length / 2.;
for (UInt frag = 0; frag < nb_fragment; ++frag) {
Real theoretical_center = initial_position + fragment_length * frag;
if (!Math::are_float_equal(fragment_center(frag, 0), theoretical_center)) {
std::cout << "The fragments' center is wrong!" << std::endl;
return EXIT_FAILURE;
}
Real initial_vel = fragment_center(frag, 0) * strain_rate;
Math::setTolerance(100);
if (!Math::are_float_equal(fragment_velocity(frag), initial_vel)) {
std::cout << "The fragments' velocity is wrong!" << std::endl;
return EXIT_FAILURE;
}
}
finalize();
std::cout << "OK: test_cohesive_buildfragments was passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/CMakeLists.txt
index bfb4e7a98..2f38e1d01 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/CMakeLists.txt
@@ -1,62 +1,63 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
-# @date creation: Tue May 08 2012
-# @date last modification: Wed Oct 09 2013
+# @date creation: Fri Oct 22 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for extrinsic cohesive elements tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_cohesive_extrinsic_mesh triangle.geo 2 1)
add_mesh(test_cohesive_extrinsic_quadrangle_mesh quadrangle.geo 2 2)
add_mesh(test_cohesive_extrinsic_tetrahedron_mesh tetrahedron.geo 3 2)
register_test(test_cohesive_extrinsic
SOURCES test_cohesive_extrinsic.cc
DEPENDS test_cohesive_extrinsic_mesh
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE cohesive_element
)
register_test(test_cohesive_extrinsic_quadrangle
SOURCES test_cohesive_extrinsic_quadrangle.cc
DEPENDS test_cohesive_extrinsic_quadrangle_mesh
PACKAGE cohesive_element
)
register_test(test_cohesive_extrinsic_tetrahedron
SOURCES test_cohesive_extrinsic_tetrahedron.cc
DEPENDS test_cohesive_extrinsic_tetrahedron_mesh
PACKAGE cohesive_element
)
register_test(test_cohesive_extrinsic_fatigue
SOURCES test_cohesive_extrinsic_fatigue.cc
FILES_TO_COPY material_fatigue.dat fatigue.msh
DIRECTORIES_TO_CREATE paraview
PACKAGE cohesive_element
)
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic.cc
index c082b26a0..84412de83 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic.cc
@@ -1,166 +1,167 @@
/**
* @file test_cohesive_extrinsic.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Wed Mar 18 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblWarning);
const UInt spatial_dimension = 2;
const UInt max_steps = 1000;
Mesh mesh(spatial_dimension);
mesh.read("triangle.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
model.limitInsertion(_y, -0.30, -0.20);
model.updateAutomaticInsertion();
Real time_step = model.getStableTimeStep()*0.05;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
boundary(n, 1) = true;
if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
boundary(n, 0) = true;
}
/// initial conditions
Real loading_rate = 0.5;
Real disp_update = loading_rate * time_step;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 1) = loading_rate * position(n, 1);
}
model.updateResidual();
model.setBaseName("extrinsic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("residual" );
model.addDumpFieldTensor("stress");
model.addDumpField("strain");
model.addDumpField("damage");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.dump();
model.dump("cohesive elements");
// std::ofstream edis("edis.txt");
// std::ofstream erev("erev.txt");
// Array<Real> & residual = model.getResidual();
// const Array<Real> & stress = model.getMaterial(0).getStress(type);
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
/// update displacement on extreme nodes
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
displacement(n, 1) += disp_update * position(n, 1);
}
model.checkCohesiveStress();
model.solveStep();
if(s % 100 == 0) {
model.dump();
model.dump("cohesive elements");
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
// Real Ed = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getDissipatedEnergy();
// Real Er = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getReversibleEnergy();
// edis << s << " "
// << Ed << std::endl;
// erev << s << " "
// << Er << std::endl;
}
// edis.close();
// erev.close();
// mesh.write("mesh_final.msh");
model.dump();
Real Ed = model.getEnergy("dissipated");
Real Edt = 200 * std::sqrt(2);
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
finalize();
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_extrinsic was passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_fatigue.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_fatigue.cc
index f0ea7695e..d52004d60 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_fatigue.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_fatigue.cc
@@ -1,233 +1,236 @@
/**
- * @file test_cohesive_intrinsic_fatigue.cc
+ * @file test_cohesive_extrinsic_fatigue.cc
+ *
* @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @date Fri Feb 20 10:13:14 2015
+ *
+ * @date creation: Fri Feb 20 2015
+ * @date last modification: Thu Jun 25 2015
*
* @brief Test for the linear fatigue cohesive law
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive_linear_fatigue.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
// the following class contains an implementation of the 1D linear
// fatigue cohesive law
class MaterialFatigue {
public:
MaterialFatigue(Real delta_f, Real sigma_c, Real delta_c) :
delta_f(delta_f), sigma_c(sigma_c), delta_c(delta_c),
delta_prec(0), traction(sigma_c), delta_max(0),
stiff_plus(std::numeric_limits<Real>::max()),
tolerance(Math::getTolerance()) {};
Real computeTraction(Real delta) {
if (delta - delta_c > -tolerance)
traction = 0;
else if (delta_max < tolerance && delta < tolerance)
traction = sigma_c;
else {
Real delta_dot = delta - delta_prec;
if (delta_dot > -tolerance) {
stiff_plus *= 1 - delta_dot / delta_f;
traction += stiff_plus * delta_dot;
Real max_traction = sigma_c * (1 - delta / delta_c);
if (traction - max_traction > -tolerance || delta_max < tolerance) {
traction = max_traction;
stiff_plus = traction / delta;
}
} else {
Real stiff_minus = traction / delta_prec;
stiff_plus += (stiff_plus - stiff_minus) * delta_dot / delta_f;
traction += stiff_minus * delta_dot;
}
}
delta_prec = delta;
delta_max = std::max(delta, delta_max);
return traction;
}
private:
const Real delta_f;
const Real sigma_c;
const Real delta_c;
Real delta_prec;
Real traction;
Real delta_max;
Real stiff_plus;
const Real tolerance;
};
void imposeOpening(SolidMechanicsModelCohesive &, Real);
void arange(Array<Real> &, Real, Real, Real);
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
initialize("material_fatigue.dat", argc, argv);
Math::setTolerance(1e-13);
const UInt spatial_dimension = 2;
const ElementType type = _quadrangle_4;
Mesh mesh(spatial_dimension);
mesh.read("fatigue.msh");
// init stuff
const ElementType type_facet = Mesh::getFacetType(type);
const ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
SolidMechanicsModelCohesive model(mesh);
model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
MaterialCohesiveLinearFatigue<2> & numerical_material
= dynamic_cast<MaterialCohesiveLinearFatigue<2> &>(model.getMaterial("cohesive"));
Real delta_f = numerical_material.getParam<Real>("delta_f");
Real delta_c = numerical_material.getParam<Real>("delta_c");
Real sigma_c = 1;
const Array<Real> & traction_array = numerical_material.getTraction(type_cohesive);
MaterialFatigue theoretical_material(delta_f, sigma_c, delta_c);
// model.setBaseName("fatigue");
// model.addDumpFieldVector("displacement");
// model.addDumpField("stress");
// model.dump();
// stretch material
Real strain = 1;
Array<Real> & displacement = model.getDisplacement();
const Array<Real> & position = mesh.getNodes();
for (UInt n = 0; n < mesh.getNbNodes(); ++n)
displacement(n, 0) = position(n, 0) * strain;
model.updateResidual();
// model.dump();
// insert cohesive elements
model.checkCohesiveStress();
// create the displacement sequence
Real increment = 0.01;
Array<Real> openings;
arange(openings, 0, 0.5, increment);
arange(openings, 0.5, 0.1, increment);
arange(openings, 0.1, 0.7, increment);
arange(openings, 0.7, 0.3, increment);
arange(openings, 0.3, 0.6, increment);
arange(openings, 0.6, 0.3, increment);
arange(openings, 0.3, 0.7, increment);
arange(openings, 0.7, 1.3, increment);
const Array<UInt> & switches = numerical_material.getSwitches(type_cohesive);
// std::ofstream edis("fatigue_edis.txt");
// impose openings
for (UInt i = 0; i < openings.getSize(); ++i) {
// compute numerical traction
imposeOpening(model, openings(i));
model.updateResidual();
// model.dump();
Real numerical_traction = traction_array(0, 0);
// compute theoretical traction
Real theoretical_traction = theoretical_material.computeTraction(openings(i));
// test traction
if (std::abs(numerical_traction - theoretical_traction) > 1e-13)
AKANTU_DEBUG_ERROR("The numerical traction " << numerical_traction
<< " and theoretical traction " << theoretical_traction
<< " are not coincident");
// edis << model.getEnergy("dissipated") << std::endl;
}
if (switches(0) != 7)
AKANTU_DEBUG_ERROR("The number of switches is wrong");
std::cout << "OK: the test_cohesive_extrinsic_fatigue passed." << std::endl;
return 0;
}
/* -------------------------------------------------------------------------- */
void imposeOpening(SolidMechanicsModelCohesive & model, Real opening) {
UInt spatial_dimension = model.getSpatialDimension();
Mesh & mesh = model.getFEEngine().getMesh();
Array<Real> & position = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
UInt nb_nodes = mesh.getNbNodes();
Array<bool> update(nb_nodes);
update.clear();
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator end = mesh.lastType(spatial_dimension);
for (; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Vector<Real> barycenter(spatial_dimension);
for (UInt el = 0; el < nb_element; ++el) {
mesh.getBarycenter(el, type, barycenter.storage());
if (barycenter(0) > 1) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity(el, n);
if (!update(node)) {
displacement(node, 0) = opening + position(node, 0);
update(node) = true;
}
}
}
}
}
}
/* -------------------------------------------------------------------------- */
void arange(Array<Real> & openings, Real begin, Real end, Real increment) {
if (begin < end) {
for (Real opening = begin; opening < end - increment / 2.; opening += increment)
openings.push_back(opening);
} else {
for (Real opening = begin; opening > end + increment / 2.; opening -= increment)
openings.push_back(opening);
}
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_quadrangle.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_quadrangle.cc
index cf10d2360..a51639c29 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_quadrangle.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_quadrangle.cc
@@ -1,203 +1,204 @@
/**
* @file test_cohesive_extrinsic_quadrangle.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Wed Oct 03 2012
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Tue May 08 2012
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test for extrinsic cohesive elements and quadrangles
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 2;
const UInt max_steps = 1000;
Mesh mesh(spatial_dimension);
mesh.read("quadrangle.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
model.limitInsertion(_y, -0.05, 0.05);
model.updateAutomaticInsertion();
Real time_step = model.getStableTimeStep()*0.05;
model.setTimeStep(time_step);
// std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
const Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
boundary(n, 1) = true;
if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
boundary(n, 0) = true;
}
model.updateResidual();
// iohelper::ElemType paraview_type = iohelper::QUAD2;
// UInt nb_element = mesh.getNbElement(type);
// /// initialize the paraview output
// iohelper::DumperParaview dumper;
// dumper.SetMode(iohelper::TEXT);
// dumper.SetPoints(mesh.getNodes().storage(),
// spatial_dimension, mesh.getNbNodes(), "explicit");
// dumper.SetConnectivity((int *)mesh.getConnectivity(type).storage(),
// paraview_type, nb_element, iohelper::C_MODE);
// dumper.AddNodeDataField(model.getDisplacement().storage(),
// spatial_dimension, "displacements");
// dumper.AddNodeDataField(model.getVelocity().storage(),
// spatial_dimension, "velocity");
// dumper.AddNodeDataField(model.getAcceleration().storage(),
// spatial_dimension, "acceleration");
// dumper.AddNodeDataField(model.getResidual().storage(),
// spatial_dimension, "forces");
// dumper.AddElemDataField(model.getMaterial(0).getStrain(type).storage(),
// spatial_dimension*spatial_dimension, "strain");
// dumper.AddElemDataField(model.getMaterial(0).getStress(type).storage(),
// spatial_dimension*spatial_dimension, "stress");
// dumper.SetEmbeddedValue("displacements", 1);
// dumper.SetEmbeddedValue("forces", 1);
// dumper.SetPrefix("paraview/");
// dumper.Init();
// dumper.Dump();
/// initial conditions
Real loading_rate = 0.2;
Real disp_update = loading_rate * time_step;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 1) = loading_rate * position(n, 1);
}
// std::ofstream edis("edis.txt");
// std::ofstream erev("erev.txt");
// Array<Real> & residual = model.getResidual();
// const Array<Real> & stress = model.getMaterial(0).getStress(type);
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
/// update displacement on extreme nodes
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
displacement(n, 1) += disp_update * position(n, 1);
}
model.checkCohesiveStress();
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
if(s % 1 == 0) {
// dumper.SetPoints(mesh.getNodes().storage(),
// spatial_dimension, mesh.getNbNodes(), "explicit");
// dumper.SetConnectivity((int *)mesh.getConnectivity(type).storage(),
// paraview_type, nb_element, iohelper::C_MODE);
// dumper.AddNodeDataField(model.getDisplacement().storage(),
// spatial_dimension, "displacements");
// dumper.AddNodeDataField(model.getVelocity().storage(),
// spatial_dimension, "velocity");
// dumper.AddNodeDataField(model.getAcceleration().storage(),
// spatial_dimension, "acceleration");
// dumper.AddNodeDataField(model.getResidual().storage(),
// spatial_dimension, "forces");
// dumper.AddElemDataField(model.getMaterial(0).getStrain(type).storage(),
// spatial_dimension*spatial_dimension, "strain");
// dumper.AddElemDataField(model.getMaterial(0).getStress(type).storage(),
// spatial_dimension*spatial_dimension, "stress");
// dumper.SetEmbeddedValue("displacements", 1);
// dumper.SetEmbeddedValue("forces", 1);
// dumper.SetPrefix("paraview/");
// dumper.Init();
// dumper.Dump();
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
// Real Ed = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getDissipatedEnergy();
// Real Er = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getReversibleEnergy();
// edis << s << " "
// << Ed << std::endl;
// erev << s << " "
// << Er << std::endl;
}
// edis.close();
// erev.close();
mesh.write("mesh_final.msh");
Real Ed = model.getEnergy("dissipated");
Real Edt = 200;
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.99 || Ed > Edt * 1.01 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_extrinsic_quadrangle was passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_tetrahedron.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_tetrahedron.cc
index b1b380e0b..1868127fe 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_tetrahedron.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_tetrahedron.cc
@@ -1,241 +1,242 @@
/**
* @file test_cohesive_extrinsic_tetrahedron.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Wed Oct 09 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Tue May 08 2012
+ * @date last modification: Thu Oct 15 2015
*
* @brief Test for serial extrinsic cohesive elements for tetrahedron
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive_linear.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
Real function(Real constant, Real x, Real y, Real z) {
return constant + 2. * x + 3. * y + 4 * z;
}
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
// const UInt max_steps = 1000;
// Real increment = 0.005;
const UInt spatial_dimension = 3;
Math::setTolerance(1.e-12);
ElementType type = _tetrahedron_10;
ElementType type_facet = Mesh::getFacetType(type);
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
Mesh mesh(spatial_dimension);
mesh.read("tetrahedron.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
const MaterialCohesiveLinear<3> & mat_cohesive
= dynamic_cast < const MaterialCohesiveLinear<3> & > (model.getMaterial(1));
std::cout << mat_cohesive << std::endl;
std::cout << model.getMaterial(2) << std::endl;
const Real sigma_c = mat_cohesive.getParam< RandomInternalField<Real, FacetInternalField> >("sigma_c");
const Real beta = mat_cohesive.getParam<Real>("beta");
// const Real G_cI = mat_cohesive.getParam<Real>("G_cI");
Array<Real> & position = mesh.getNodes();
/* ------------------------------------------------------------------------ */
/* Facet part */
/* ------------------------------------------------------------------------ */
/// compute quadrature points positions on facets
const Mesh & mesh_facets = model.getMeshFacets();
UInt nb_facet = mesh_facets.getNbElement(type_facet);
UInt nb_quad_per_facet = model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
UInt nb_tot_quad = nb_quad_per_facet * nb_facet;
Array<Real> quad_facets(nb_tot_quad, spatial_dimension);
model.getFEEngine("FacetsFEEngine").interpolateOnIntegrationPoints(position,
quad_facets,
spatial_dimension,
type_facet);
/* ------------------------------------------------------------------------ */
/* End of facet part */
/* ------------------------------------------------------------------------ */
/// compute quadrature points position of the elements
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
UInt nb_element = mesh.getNbElement(type);
UInt nb_tot_quad_el = nb_quad_per_element * nb_element;
Array<Real> quad_elements(nb_tot_quad_el, spatial_dimension);
model.getFEEngine().interpolateOnIntegrationPoints(position,
quad_elements,
spatial_dimension,
type);
/// assign some values to stresses
Array<Real> & stress
= const_cast<Array<Real>&>(model.getMaterial(0).getStress(type));
Array<Real>::iterator<Matrix<Real> > stress_it
= stress.begin(spatial_dimension, spatial_dimension);
for (UInt q = 0; q < nb_tot_quad_el; ++q, ++stress_it) {
/// compute values
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = i; j < spatial_dimension; ++j) {
UInt index = i * spatial_dimension + j;
(*stress_it)(i, j) = index * function(sigma_c * 5,
quad_elements(q, 0),
quad_elements(q, 1),
quad_elements(q, 2));
}
}
/// fill symmetrical part
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < i; ++j) {
(*stress_it)(i, j) = (*stress_it)(j, i);
}
}
}
/// compute stress on facet quads
Array<Real> stress_facets(nb_tot_quad, spatial_dimension * spatial_dimension);
Array<Real>::iterator<Matrix<Real> > stress_facets_it
= stress_facets.begin(spatial_dimension, spatial_dimension);
for (UInt q = 0; q < nb_tot_quad; ++q, ++stress_facets_it) {
/// compute values
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = i; j < spatial_dimension; ++j) {
UInt index = i * spatial_dimension + j;
(*stress_facets_it)(i, j) = index * function(sigma_c * 5,
quad_facets(q, 0),
quad_facets(q, 1),
quad_facets(q, 2));
}
}
/// fill symmetrical part
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < i; ++j) {
(*stress_facets_it)(i, j) = (*stress_facets_it)(j, i);
}
}
}
/// insert cohesive elements
model.checkCohesiveStress();
/// check insertion stress
const Array<Real> & normals =
model.getFEEngine("FacetsFEEngine").getNormalsOnIntegrationPoints(type_facet);
const Array<Real> & tangents = model.getTangents(type_facet);
const Array<Real> & sigma_c_eff = mat_cohesive.getInsertionTraction(type_cohesive);
Vector<Real> normal_stress(spatial_dimension);
const Array<std::vector<Element> > & coh_element_to_facet
= mesh_facets.getElementToSubelement(type_facet);
Array<Real>::iterator<Matrix<Real> > quad_facet_stress
= stress_facets.begin(spatial_dimension, spatial_dimension);
Array<Real>::const_iterator<Vector<Real> > quad_normal
= normals.begin(spatial_dimension);
Array<Real>::const_iterator<Vector<Real> > quad_tangents
= tangents.begin(tangents.getNbComponent());
for (UInt f = 0; f < nb_facet; ++f) {
const Element & cohesive_element = coh_element_to_facet(f)[1];
for (UInt q = 0; q < nb_quad_per_facet; ++q, ++quad_facet_stress,
++quad_normal, ++quad_tangents) {
if (cohesive_element == ElementNull) continue;
normal_stress.mul<false>(*quad_facet_stress, *quad_normal);
Real normal_contrib = normal_stress.dot(*quad_normal);
Real first_tangent_contrib = 0;
for (UInt dim = 0; dim < spatial_dimension; ++dim)
first_tangent_contrib += normal_stress(dim) * (*quad_tangents)(dim);
Real second_tangent_contrib = 0;
for (UInt dim = 0; dim < spatial_dimension; ++dim)
second_tangent_contrib
+= normal_stress(dim) * (*quad_tangents)(dim + spatial_dimension);
Real tangent_contrib = std::sqrt(first_tangent_contrib * first_tangent_contrib +
second_tangent_contrib * second_tangent_contrib);
normal_contrib = std::max(0., normal_contrib);
Real effective_norm = std::sqrt(normal_contrib * normal_contrib
+ tangent_contrib * tangent_contrib / beta / beta);
if (effective_norm < sigma_c) continue;
if (!Math::are_float_equal(effective_norm,
sigma_c_eff(cohesive_element.element
* nb_quad_per_facet + q))) {
std::cout << "Insertion tractions do not match" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
}
finalize();
std::cout << "OK: test_cohesive_extrinsic was passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/CMakeLists.txt
index 0bf4aea54..5f112388c 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/CMakeLists.txt
@@ -1,37 +1,38 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Mauro Corrado <mauro.corrado@epfl.ch>
#
-# @date Fri May 01 11:56:18 2015
+# @date creation: Tue Dec 07 2010
+# @date last modification: Tue Jun 16 2015
#
# @brief checking correct assembling of stiffness matrix in case of cohe elems
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
-
register_test(test_assembling_K_cohe_elements
SOURCES test_assembling_K_cohe_elements.cc
FILES_TO_COPY quadrangle.msh material.dat K_matrix_verified.dat
PACKAGE cohesive_element
)
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/test_assembling_K_cohe_elements.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/test_assembling_K_cohe_elements.cc
index 0a97d4e64..2d56814a4 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/test_assembling_K_cohe_elements.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/test_assembling_K_cohe_elements.cc
@@ -1,165 +1,166 @@
/**
- * @file matrix_assembling_cohesive_elements.cc
+ * @file test_assembling_K_cohe_elements.cc
*
- * @author Mauro Corrado
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
*
- * @date creation: Thu April 30 2015
+ * @date creation: Fri May 15 2015
+ * @date last modification: Thu Aug 20 2015
*
* @brief Test to check the correct matrix assembling for cohesive elements
- * with degenerated nodes
+ * with degenerated nodes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblWarning);
const UInt spatial_dimension = 2;
Real increment = 0.004;
Real error;
bool passed = true;
Real tol = 1.0e-13;
Mesh mesh(spatial_dimension);
mesh.read("quadrangle.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelCohesiveOptions(_static, true));
/// CohesiveElementInserter
model.limitInsertion(_y, -0.001, 0.001);
model.updateAutomaticInsertion();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & position = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
//SparseMatrix & K_test = model.getStiffnessMatrix();
Array<Real> K_verified(0,3, "K_matrix_verified");
Array<Real> K_test(0,3, "K_matrix_test");
/// load the verified stiffness matrix
Vector<Real> tmp(3);
UInt nb_lines;
std::ifstream infile("K_matrix_verified.dat");
std::string line;
if(!infile.good()) AKANTU_DEBUG_ERROR("Cannot open file K_matrix_verified.dat");
else{
for (UInt i = 0; i < 2; ++i){
getline(infile, line);
std::stringstream sstr_data(line);
if (i == 1){
sstr_data >> tmp(0) >> tmp(1) >> tmp(2);
nb_lines = tmp(2);
}
}
for (UInt i = 0; i < nb_lines; ++i){
getline(infile, line);
std::stringstream sstr_data(line);
sstr_data >> tmp(0) >> tmp(1) >> tmp(2);
K_verified.push_back(tmp);
}
}
infile.close();
/// impose boundary conditions
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (position(n,1) < -0.99){
boundary(n,1) = true;
boundary(n,0) = true;
}
if (position(n,1) > 0.99 && position(n,0) < -0.99)
boundary(n,1) = true;
}
/// solve step
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (position(n,1) > 0.99 && position(n,0) < -0.99)
displacement(n,1) += increment;
}
model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(1e-13, error, 10);
model.getStiffnessMatrix().saveMatrix("K_matrix_test.dat");
/// load the stiffness matrix to be tested
std::ifstream infile2("K_matrix_test.dat");
if(!infile2.good()) AKANTU_DEBUG_ERROR("Cannot open file K_matrix_test.dat");
else{
for (UInt i = 0; i < 2; ++i){
getline(infile2, line);
std::stringstream sstr_data(line);
if (i == 1){
sstr_data >> tmp(0) >> tmp(1) >> tmp(2);
nb_lines = tmp(2);
}
}
for (UInt i = 0; i < nb_lines; ++i){
getline(infile2, line);
std::stringstream sstr_data(line);
sstr_data >> tmp(0) >> tmp(1) >> tmp(2);
K_test.push_back(tmp);
}
}
infile2.close();
for (UInt i = 0; i < K_verified.getSize(); ++i){
for (UInt j = 0; j < K_test.getSize(); ++j){
if ((K_test(j,0) == K_verified(i,0)) && (K_test(j,1) == K_verified(i,1))){
if (std::abs(K_verified(i,2)) < tol){
if (std::abs(K_test(j,2)) > tol)
passed = false;
}else{
Real ratio = (std::abs(K_test(j,2) - K_verified(i,2))) / (std::abs(K_verified(i,2)));
if (ratio > tol)
passed = false;
}
}
}
}
finalize();
if (passed)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/CMakeLists.txt
index dbe33abc3..f45fe1b10 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/CMakeLists.txt
@@ -1,39 +1,41 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Fabian Barras <fabian.barras@epfl.ch>
#
-# @date creation: Fri Aug 7 09:07:44 2015
-#
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 07 2015
+#
# @brief Tests insertion of cohesive elements
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(3d_spherical_inclusion 3d_spherical_inclusion.geo 3 2)
register_test(test_cohesive_insertion_along_physical_surfaces
SOURCES test_cohesive_insertion_along_physical_surfaces.cc
DEPENDS 3d_spherical_inclusion
FILES_TO_COPY input_file.dat
PACKAGE cohesive_element
)
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/test_cohesive_insertion_along_physical_surfaces.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/test_cohesive_insertion_along_physical_surfaces.cc
index e06086043..49ad5d256 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/test_cohesive_insertion_along_physical_surfaces.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/test_cohesive_insertion_along_physical_surfaces.cc
@@ -1,97 +1,99 @@
/**
* @file test_cohesive_insertion_along_physical_surfaces.cc
+ *
* @author Fabian Barras <fabian.barras@epfl.ch>
- * @date Fri Aug 7 09:07:44 2015
*
- * @brief Test intrinsic insertion of cohesive elements along physical surfaces
+ * @date creation: Fri Aug 07 2015
+ *
+ * @brief Test intrinsic insertion of cohesive elements along physical surfaces
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "mesh_utils.hh"
#include "solid_mechanics_model_cohesive.hh"
#include "material.hh"
#include "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("input_file.dat", argc, argv);
Math::setTolerance(1e-15);
const UInt spatial_dimension = 3;
Mesh mesh(spatial_dimension);
mesh.read("3d_spherical_inclusion.msh");
SolidMechanicsModelCohesive model(mesh);
mesh.createGroupsFromMeshData<std::string>("physical_names");
model.initFull(SolidMechanicsModelCohesiveOptions(_static));
std::vector<std::string> surfaces_name = {"interface", "coh1", "coh2", "coh3", "coh4", "coh5"};
UInt nb_surf = surfaces_name.size();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, _ek_cohesive);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, _not_ghost, _ek_cohesive);
for(; it != end; ++it) {
for (UInt i = 0; i < nb_surf; ++i) {
UInt expected_insertion = mesh.getElementGroup(surfaces_name[i]).getElements(mesh.getFacetType(*it)).getSize();
UInt inserted_elements = model.getMaterial(surfaces_name[i]).getElementFilter()(*it).getSize();
AKANTU_DEBUG_ASSERT((expected_insertion == inserted_elements),
std::endl << "!!! Mismatch in insertion of surface named "
<< surfaces_name[i]
<< " --> " << inserted_elements << " inserted elements out of "
<< expected_insertion << std::endl);
}
}
/*std::string paraview_folder = "paraview/test_intrinsic_insertion_along_physical_surfaces/";
model.setDirectory(paraview_folder);
model.setBaseName("bulk");
model.addDumpField("partitions");
model.dump();
model.setDirectoryToDumper("cohesive elements", paraview_folder);
model.setBaseNameToDumper("cohesive elements", "one_cohesive_element");
model.addDumpFieldToDumper("cohesive elements", "partitions");
model.addDumpFieldToDumper("cohesive elements", "material_index");
model.dump("cohesive elements");
*/
model.assembleStiffnessMatrix();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/CMakeLists.txt
index bb6a8d167..14c8bfbf9 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/CMakeLists.txt
@@ -1,63 +1,64 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
-# @date creation: Tue May 08 2012
-# @date last modification: Tue Nov 12 2013
+# @date creation: Fri Oct 22 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief test for intrinsic cohesive element configuration
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_cohesive_intrinsic_mesh triangle.geo 2 2)
add_mesh(test_cohesive_intrinsic_quadrangle_mesh quadrangle.geo 2 1)
add_mesh(test_cohesive_intrinsic_tetrahedron_mesh tetrahedron.geo 3 2)
add_mesh(test_cohesive_intrinsic_tetrahedron_fragmentation_mesh tetrahedron_full.geo 3 2)
register_test(test_cohesive_intrinsic
SOURCES test_cohesive_intrinsic.cc
DEPENDS test_cohesive_intrinsic_mesh
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE cohesive_element
)
register_test(test_cohesive_intrinsic_quadrangle
SOURCES test_cohesive_intrinsic_quadrangle.cc
DEPENDS test_cohesive_intrinsic_quadrangle_mesh
PACKAGE cohesive_element
)
register_test(test_cohesive_intrinsic_tetrahedron
SOURCES test_cohesive_intrinsic_tetrahedron.cc
DEPENDS test_cohesive_intrinsic_tetrahedron_mesh
FILES_TO_COPY material_tetrahedron.dat
PACKAGE cohesive_element
)
register_test(test_cohesive_intrinsic_tetrahedron_fragmentation
SOURCES test_cohesive_intrinsic_tetrahedron_fragmentation.cc
DEPENDS test_cohesive_intrinsic_tetrahedron_fragmentation_mesh
PACKAGE cohesive_element
)
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic.cc
index 67db8bed2..d3abce065 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic.cc
@@ -1,191 +1,192 @@
/**
* @file test_cohesive_intrinsic.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "mesh_utils.hh"
#include "solid_mechanics_model_cohesive.hh"
#include "material.hh"
#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
static void updateDisplacement(SolidMechanicsModelCohesive &,
Array<UInt> &,
ElementType,
Real);
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblWarning);
const UInt spatial_dimension = 2;
const UInt max_steps = 350;
const ElementType type = _triangle_6;
Mesh mesh(spatial_dimension);
mesh.read("triangle.msh");
std::cout << mesh << std::endl;
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull();
model.limitInsertion(_x, -0.26, -0.24);
model.insertIntrinsicElements();
mesh.write("mesh_cohesive.msh");
Real time_step = model.getStableTimeStep()*0.8;
model.setTimeStep(time_step);
// std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
Array<bool> & boundary = model.getBlockedDOFs();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_element = mesh.getNbElement(type);
/// boundary conditions
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
for (UInt n = 0; n < nb_nodes; ++n) {
boundary(n, dim) = true;
}
}
model.updateResidual();
model.setBaseName("intrinsic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("residual" );
model.addDumpField("stress");
model.addDumpField("strain");
model.addDumpField("force");
model.dump();
model.setBaseNameToDumper("cohesive elements",
"cohesive_elements_triangle");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump("cohesive elements");
/// update displacement
Array<UInt> elements;
Real * bary = new Real[spatial_dimension];
for (UInt el = 0; el < nb_element; ++el) {
mesh.getBarycenter(el, type, bary);
if (bary[0] > -0.25) elements.push_back(el);
}
delete[] bary;
Real increment = 0.01;
updateDisplacement(model, elements, type, increment);
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
model.solveStep();
updateDisplacement(model, elements, type, increment);
if(s % 1 == 0) {
model.dump();
model.dump("cohesive elements");
std::cout << "passing step " << s << "/" << max_steps
<< ", Ed = " << model.getEnergy("dissipated") << std::endl;
}
}
Real Ed = model.getEnergy("dissipated");
Real Edt = 2 * sqrt(2);
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_intrinsic was passed!" << std::endl;
return EXIT_SUCCESS;
}
static void updateDisplacement(SolidMechanicsModelCohesive & model,
Array<UInt> & elements,
ElementType type,
Real increment) {
Mesh & mesh = model.getFEEngine().getMesh();
UInt nb_element = elements.getSize();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Array<Real> & displacement = model.getDisplacement();
Array<bool> update(nb_nodes);
update.clear();
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity(elements(el), n);
if (!update(node)) {
displacement(node, 0) += increment;
// displacement(node, 1) += increment;
update(node) = true;
}
}
}
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_quadrangle.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_quadrangle.cc
index 3b5793aaa..22e160809 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_quadrangle.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_quadrangle.cc
@@ -1,225 +1,226 @@
/**
* @file test_cohesive_intrinsic_quadrangle.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Wed Oct 03 2012
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Tue May 08 2012
+ * @date last modification: Thu Dec 11 2014
*
* @brief Intrinsic cohesive elements' test for quadrangles
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
static void updateDisplacement(SolidMechanicsModelCohesive &,
Array<UInt> &,
ElementType,
Real);
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 2;
const UInt max_steps = 350;
const ElementType type = _quadrangle_4;
Mesh mesh(spatial_dimension);
mesh.read("quadrangle.msh");
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// debug::setDebugLevel(dblWarning);
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull();
model.limitInsertion(_x, -0.01, 0.01);
model.insertIntrinsicElements();
// mesh.write("mesh_cohesive_quadrangle.msh");
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// debug::setDebugLevel(dblWarning);
Real time_step = model.getStableTimeStep()*0.8;
model.setTimeStep(time_step);
// std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
Array<bool> & boundary = model.getBlockedDOFs();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_element = mesh.getNbElement(type);
/// boundary conditions
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
for (UInt n = 0; n < nb_nodes; ++n) {
boundary(n, dim) = true;
}
}
model.updateResidual();
model.setBaseName("intrinsic_quadrangle");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("residual" );
model.addDumpField("stress");
model.addDumpField("grad_u");
model.addDumpField("force");
model.setBaseNameToDumper("cohesive elements", "cohesive_elements_quadrangle");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump();
model.dump("cohesive elements");
/// update displacement
Array<UInt> elements;
Real * bary = new Real[spatial_dimension];
for (UInt el = 0; el < nb_element; ++el) {
mesh.getBarycenter(el, type, bary);
if (bary[0] > 0.) elements.push_back(el);
}
delete[] bary;
Real increment = 0.01;
updateDisplacement(model, elements, type, increment);
// for (UInt n = 0; n < nb_nodes; ++n) {
// if (position(n, 1) + displacement(n, 1) > 0) {
// if (position(n, 0) == 0) {
// displacement(n, 1) -= 0.25;
// }
// if (position(n, 0) == 1) {
// displacement(n, 1) += 0.25;
// }
// }
// }
// std::ofstream edis("edis.txt");
// std::ofstream erev("erev.txt");
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
updateDisplacement(model, elements, type, increment);
if(s % 1 == 0) {
model.dump();
model.dump("cohesive elements");
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
// // update displacement
// for (UInt n = 0; n < nb_nodes; ++n) {
// if (position(n, 1) + displacement(n, 1) > 0) {
// displacement(n, 0) -= 0.01;
// }
// }
// Real Ed = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getDissipatedEnergy();
// Real Er = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getReversibleEnergy();
// edis << s << " "
// << Ed << std::endl;
// erev << s << " "
// << Er << std::endl;
}
// edis.close();
// erev.close();
Real Ed = model.getEnergy("dissipated");
Real Edt = 1;
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001) {
std::cout << "The dissipated energy is incorrect" << std::endl;
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_intrinsic_quadrangle was passed!" << std::endl;
return EXIT_SUCCESS;
}
static void updateDisplacement(SolidMechanicsModelCohesive & model,
Array<UInt> & elements,
ElementType type,
Real increment) {
Mesh & mesh = model.getFEEngine().getMesh();
UInt nb_element = elements.getSize();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Array<Real> & displacement = model.getDisplacement();
Array<bool> update(nb_nodes);
update.clear();
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity(elements(el), n);
if (!update(node)) {
displacement(node, 0) += increment;
// displacement(node, 1) += increment;
update(node) = true;
}
}
}
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_tetrahedron.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_tetrahedron.cc
index 006fc26a5..5354320c7 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_tetrahedron.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_tetrahedron.cc
@@ -1,440 +1,440 @@
/**
* @file test_cohesive_intrinsic_tetrahedron.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Aug 27 2013
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
void updateDisplacement(SolidMechanicsModelCohesive &,
Array<UInt> &,
ElementType,
Vector<Real> &);
bool checkTractions(SolidMechanicsModelCohesive & model,
ElementType type,
Vector<Real> & opening,
Vector<Real> & theoretical_traction,
Matrix<Real> & rotation);
void findNodesToCheck(const Mesh & mesh,
const Array<UInt> & elements,
ElementType type,
Array<UInt> & nodes_to_check);
bool checkEquilibrium(const Array<Real> & residual);
bool checkResidual(const Array<Real> & residual,
const Vector<Real> & traction,
const Array<UInt> & nodes_to_check,
const Matrix<Real> & rotation);
int main(int argc, char *argv[]) {
initialize("material_tetrahedron.dat", argc, argv);
// debug::setDebugLevel(dblDump);
const UInt spatial_dimension = 3;
const UInt max_steps = 60;
const Real increment_constant = 0.01;
Math::setTolerance(1.e-12);
const ElementType type = _tetrahedron_10;
Mesh mesh(spatial_dimension);
mesh.read("tetrahedron.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull();
model.limitInsertion(_x, -0.01, 0.01);
model.insertIntrinsicElements();
Array<bool> & boundary = model.getBlockedDOFs();
boundary.set(true);
UInt nb_element = mesh.getNbElement(type);
model.updateResidual();
model.setBaseName("intrinsic_tetrahedron");
model.addDumpFieldVector("displacement");
model.addDumpField("residual");
model.dump();
model.setBaseNameToDumper("cohesive elements", "cohesive_elements_tetrahedron");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump("cohesive elements");
/// find elements to displace
Array<UInt> elements;
Real * bary = new Real[spatial_dimension];
for (UInt el = 0; el < nb_element; ++el) {
mesh.getBarycenter(el, type, bary);
if (bary[0] > 0.01) elements.push_back(el);
}
delete[] bary;
/// find nodes to check
Array<UInt> nodes_to_check;
findNodesToCheck(mesh, elements, type, nodes_to_check);
/// rotate mesh
Real angle = 1.;
Matrix<Real> rotation(spatial_dimension, spatial_dimension);
rotation.clear();
rotation(0, 0) = std::cos(angle);
rotation(0, 1) = std::sin(angle) * -1.;
rotation(1, 0) = std::sin(angle);
rotation(1, 1) = std::cos(angle);
rotation(2, 2) = 1.;
Vector<Real> increment_tmp(spatial_dimension);
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
increment_tmp(dim) = (dim + 1) * increment_constant;
}
Vector<Real> increment(spatial_dimension);
increment.mul<false>(rotation, increment_tmp);
Array<Real> & position = mesh.getNodes();
Array<Real> position_tmp(position);
Array<Real>::iterator<Vector<Real> > position_it = position.begin(spatial_dimension);
Array<Real>::iterator<Vector<Real> > position_end = position.end(spatial_dimension);
Array<Real>::iterator<Vector<Real> > position_tmp_it
= position_tmp.begin(spatial_dimension);
for (; position_it != position_end; ++position_it, ++position_tmp_it)
position_it->mul<false>(rotation, *position_tmp_it);
model.dump();
model.dump("cohesive elements");
updateDisplacement(model, elements, type, increment);
Real theoretical_Ed = 0;
Vector<Real> opening(spatial_dimension);
Vector<Real> traction(spatial_dimension);
Vector<Real> opening_old(spatial_dimension);
Vector<Real> traction_old(spatial_dimension);
opening.clear();
traction.clear();
opening_old.clear();
traction_old.clear();
Vector<Real> Dt(spatial_dimension);
Vector<Real> Do(spatial_dimension);
const Array<Real> & residual = model.getResidual();
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
model.updateResidual();
opening += increment_tmp;
if (checkTractions(model, type, opening, traction, rotation) ||
checkEquilibrium(residual) ||
checkResidual(residual, traction, nodes_to_check, rotation)) {
finalize();
return EXIT_FAILURE;
}
/// compute energy
Do = opening;
Do -= opening_old;
Dt = traction_old;
Dt += traction;
theoretical_Ed += .5 * Do.dot(Dt);
opening_old = opening;
traction_old = traction;
updateDisplacement(model, elements, type, increment);
if(s % 10 == 0) {
std::cout << "passing step " << s << "/" << max_steps << std::endl;
model.dump();
model.dump("cohesive elements");
}
}
model.dump();
model.dump("cohesive elements");
Real Ed = model.getEnergy("dissipated");
theoretical_Ed *= 4.;
std::cout << Ed << " " << theoretical_Ed << std::endl;
if (!Math::are_float_equal(Ed, theoretical_Ed) || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
finalize();
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_intrinsic_tetrahedron was passed!" << std::endl;
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
void updateDisplacement(SolidMechanicsModelCohesive & model,
Array<UInt> & elements,
ElementType type,
Vector<Real> & increment) {
UInt spatial_dimension = model.getSpatialDimension();
Mesh & mesh = model.getFEEngine().getMesh();
UInt nb_element = elements.getSize();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Array<Real> & displacement = model.getDisplacement();
Array<bool> update(nb_nodes);
update.clear();
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity(elements(el), n);
if (!update(node)) {
Vector<Real> node_disp(displacement.storage() + node * spatial_dimension,
spatial_dimension);
node_disp += increment;
update(node) = true;
}
}
}
}
/* -------------------------------------------------------------------------- */
bool checkTractions(SolidMechanicsModelCohesive & model,
ElementType type,
Vector<Real> & opening,
Vector<Real> & theoretical_traction,
Matrix<Real> & rotation) {
UInt spatial_dimension = model.getSpatialDimension();
const MaterialCohesive & mat_cohesive
= dynamic_cast < const MaterialCohesive & > (model.getMaterial(1));
Real sigma_c = mat_cohesive.getParam< RandomInternalField<Real, FacetInternalField> >("sigma_c");
const Real beta = mat_cohesive.getParam<Real>("beta");
const Real G_c = mat_cohesive.getParam<Real>("G_c");
const Real delta_0 = mat_cohesive.getParam<Real>("delta_0");
const Real kappa = mat_cohesive.getParam<Real>("kappa");
Real delta_c = 2 * G_c / sigma_c;
sigma_c *= delta_c / (delta_c - delta_0);
ElementType type_facet = Mesh::getFacetType(type);
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
const Array<Real> & traction = mat_cohesive.getTraction(type_cohesive);
const Array<Real> & damage = mat_cohesive.getDamage(type_cohesive);
UInt nb_quad_per_el
= model.getFEEngine("CohesiveFEEngine").getNbIntegrationPoints(type_cohesive);
UInt nb_element = model.getMesh().getNbElement(type_cohesive);
UInt tot_nb_quad = nb_element * nb_quad_per_el;
Vector<Real> normal_opening(spatial_dimension);
normal_opening.clear();
normal_opening(0) = opening(0);
Real normal_opening_norm = normal_opening.norm();
Vector<Real> tangential_opening(spatial_dimension);
tangential_opening.clear();
for (UInt dim = 1; dim < spatial_dimension; ++dim)
tangential_opening(dim) = opening(dim);
Real tangential_opening_norm = tangential_opening.norm();
Real beta2_kappa2 = beta * beta/kappa/kappa;
Real beta2_kappa = beta * beta/kappa;
Real delta = std::sqrt(tangential_opening_norm * tangential_opening_norm
* beta2_kappa2 +
normal_opening_norm * normal_opening_norm);
delta = std::max(delta, delta_0);
Real theoretical_damage = std::min(delta / delta_c, 1.);
if (Math::are_float_equal(theoretical_damage, 1.))
theoretical_traction.clear();
else {
theoretical_traction = tangential_opening;
theoretical_traction *= beta2_kappa;
theoretical_traction += normal_opening;
theoretical_traction *= sigma_c / delta * (1. - theoretical_damage);
}
// adjust damage
theoretical_damage = std::max((delta - delta_0) / (delta_c - delta_0), 0.);
theoretical_damage = std::min(theoretical_damage, 1.);
Vector<Real> theoretical_traction_rotated(spatial_dimension);
theoretical_traction_rotated.mul<false>(rotation, theoretical_traction);
for (UInt q = 0; q < tot_nb_quad; ++q) {
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
if (!Math::are_float_equal(theoretical_traction_rotated(dim),
traction(q, dim))) {
std::cout << "Tractions are incorrect" << std::endl;
return 1;
}
}
if (!Math::are_float_equal(theoretical_damage, damage(q))) {
std::cout << "Damage is incorrect" << std::endl;
return 1;
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
void findNodesToCheck(const Mesh & mesh,
const Array<UInt> & elements,
ElementType type,
Array<UInt> & nodes_to_check) {
const Array<UInt> & connectivity = mesh.getConnectivity(type);
const Array<Real> & position = mesh.getNodes();
UInt nb_nodes = position.getSize();
UInt nb_nodes_per_elem = connectivity.getNbComponent();
Array<bool> checked_nodes(nb_nodes);
checked_nodes.clear();
for (UInt el = 0; el < elements.getSize(); ++el) {
UInt element = elements(el);
Vector<UInt> conn_el(connectivity.storage() + nb_nodes_per_elem * element,
nb_nodes_per_elem);
for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
UInt node = conn_el(n);
if (Math::are_float_equal(position(node, 0), 0.)
&& checked_nodes(node) == false) {
checked_nodes(node) = true;
nodes_to_check.push_back(node);
}
}
}
}
/* -------------------------------------------------------------------------- */
bool checkEquilibrium(const Array<Real> & residual) {
UInt spatial_dimension = residual.getNbComponent();
Vector<Real> residual_sum(spatial_dimension);
residual_sum.clear();
Array<Real>::const_iterator<Vector<Real> > res_it
= residual.begin(spatial_dimension);
Array<Real>::const_iterator<Vector<Real> > res_end
= residual.end(spatial_dimension);
for (; res_it != res_end; ++res_it)
residual_sum += *res_it;
for (UInt s = 0; s < spatial_dimension; ++s) {
if (!Math::are_float_equal(residual_sum(s), 0.)) {
std::cout << "System is not in equilibrium!" << std::endl;
return 1;
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
bool checkResidual(const Array<Real> & residual,
const Vector<Real> & traction,
const Array<UInt> & nodes_to_check,
const Matrix<Real> & rotation) {
UInt spatial_dimension = residual.getNbComponent();
Vector<Real> total_force(spatial_dimension);
total_force.clear();
for (UInt n = 0; n < nodes_to_check.getSize(); ++n) {
UInt node = nodes_to_check(n);
Vector<Real> res(residual.storage() + node * spatial_dimension,
spatial_dimension);
total_force += res;
}
Vector<Real> theoretical_total_force(spatial_dimension);
theoretical_total_force.mul<false>(rotation, traction);
theoretical_total_force *= -1 * 2 * 2;
for (UInt s = 0; s < spatial_dimension; ++s) {
if (!Math::are_float_equal(total_force(s), theoretical_total_force(s))) {
std::cout << "Total force isn't correct!" << std::endl;
return 1;
}
}
return 0;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_tetrahedron_fragmentation.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_tetrahedron_fragmentation.cc
index 3b97f1220..d572cf53c 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_tetrahedron_fragmentation.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_tetrahedron_fragmentation.cc
@@ -1,129 +1,129 @@
/**
* @file test_cohesive_intrinsic_tetrahedron_fragmentation.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Oct 09 2013
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Thu Dec 11 2014
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
// debug::setDebugLevel(dblDump);
ElementType type = _tetrahedron_10;
const UInt spatial_dimension = 3;
const UInt max_steps = 100;
Mesh mesh(spatial_dimension);
mesh.read("tetrahedron_full.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull();
model.insertIntrinsicElements();
Real time_step = model.getStableTimeStep()*0.8;
model.setTimeStep(time_step);
// std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
model.updateResidual();
model.setBaseName("intrinsic_tetrahedron_fragmentation");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("residual" );
model.addDumpField("stress");
model.addDumpField("grad_u");
model.setBaseNameToDumper("cohesive elements",
"cohesive_elements_tetrahedron_fragmentation");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump();
model.dump("cohesive elements");
/// update displacement
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
Real * bary = new Real[spatial_dimension];
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Array<Real> & displacement = model.getDisplacement();
Array<bool> update(nb_nodes);
for (UInt s = 0; s < max_steps; ++s) {
Real increment = s / 10.;
update.clear();
for (UInt el = 0; el < nb_element; ++el) {
mesh.getBarycenter(el, type, bary);
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity(el, n);
if (!update(node)) {
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
displacement(node, dim) = increment * bary[dim];
update(node) = true;
}
}
}
}
if (s % 10 == 0) {
model.dump();
model.dump("cohesive elements");
}
}
delete[] bary;
if (nb_nodes != nb_element * Mesh::getNbNodesPerElement(type)) {
std::cout << "Wrong number of nodes" << std::endl;
finalize();
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_intrinsic_tetrahedron was passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/CMakeLists.txt
index e251d97d0..2777b3a63 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/CMakeLists.txt
@@ -1,39 +1,40 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
-# @date creation: Mon Jul 09 2012
-# @date last modification: Fri Feb 22 2013
+# @date creation: Fri Oct 22 2010
+# @date last modification: Tue Dec 02 2014
#
# @brief configuration for intrinsic implicit cohesive elements
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
register_test(test_cohesive_intrinsic_impl
SOURCES test_cohesive_intrinsic_impl.cc
FILES_TO_COPY material.dat implicit.msh
DIRECTORIES_TO_CREATE paraview
PACKAGE cohesive_element
)
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/test_cohesive_intrinsic_impl.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/test_cohesive_intrinsic_impl.cc
index c24bcf065..38582c301 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/test_cohesive_intrinsic_impl.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/test_cohesive_intrinsic_impl.cc
@@ -1,165 +1,166 @@
/**
* @file test_cohesive_intrinsic_impl.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Mon Jul 09 2012
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblError);
const UInt spatial_dimension = 2;
const ElementType type = _triangle_6;
Mesh mesh(spatial_dimension);
mesh.read("implicit.msh");
CohesiveElementInserter inserter(mesh);
inserter.setLimit(_y, 0.9, 1.1);
inserter.insertIntrinsicElements();
// mesh.write("implicit_cohesive.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelCohesiveOptions(_static));
/// boundary conditions
Array<bool> & boundary = model.getBlockedDOFs();
UInt nb_nodes = mesh.getNbNodes();
Array<Real> & position = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
const ElementType type_facet = mesh.getFacetType(type);
for (UInt n = 0; n < nb_nodes; ++n) {
if (std::abs(position(n,1))< Math::getTolerance()){
boundary(n, 1) = true;
displacement(n,1) = 0.0;
}
if ((std::abs(position(n,0))< Math::getTolerance())&& (position(n,1)< 1.1)){
boundary(n, 0) = true;
displacement(n,0) = 0.0;
}
if ((std::abs(position(n,0)-1)< Math::getTolerance())&&(std::abs(position(n,1)-1)< Math::getTolerance())){
boundary(n, 0) = true;
displacement(n,0) = 0.0;
}
if (std::abs(position(n,1)-2)< Math::getTolerance()){
boundary(n, 1) = true;
}
}
model.setBaseName("intrinsic_impl");
model.addDumpField("displacement");
// model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
// model.addDumpField("damage" );
model.addDumpField("stress" );
model.addDumpField("strain" );
model.dump();
const MaterialCohesive & mat_coh = dynamic_cast< const MaterialCohesive &> (model.getMaterial(1));
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
const Array<Real> & opening = mat_coh.getOpening(type_cohesive);
//const Array<Real> & traction = mat_coh.getTraction(type_cohesive);
model.updateResidual();
const Array<Real> & residual = model.getResidual();
UInt max_step = 1000;
Real increment = 3./max_step;
Real error_tol = 10e-6;
std::ofstream fout;
fout.open("output");
/// Main loop
for ( UInt nstep = 0; nstep < max_step; ++nstep){
for (UInt n = 0; n < nb_nodes; ++n) {
if (std::abs(position(n,1)-2)< Math::getTolerance()){
displacement(n,1) += increment;
}
}
__attribute__ ((unused)) bool converged = model.solveStep<_scm_newton_raphson_tangent, _scc_residual>(1e-5, 100);
AKANTU_DEBUG_ASSERT(converged, "Did not converge");
// model.dump();
Real resid = 0;
for (UInt n = 0; n < nb_nodes; ++n) {
if (std::abs(position(n, 1) - 2.)/2. < Math::getTolerance()){
resid += residual(n, 1);
}
}
Real analytical = exp(1) * std::abs(opening(0, 1)) * exp (-std::abs(opening(0, 1))/0.5)/0.5;
//the residual force is comparing with the theoretical value of the cohesive law
error_tol = std::abs((std::abs(resid) - analytical)/analytical);
fout << nstep << " " << -resid << " " << analytical << " " << error_tol << std::endl;
if (error_tol > 1e-3) {
std::cout << "Relative error: " << error_tol << std::endl;
std::cout << "Test failed!" << std::endl;
return EXIT_FAILURE;
}
}
model.dump();
fout.close();
finalize();
std::cout << "Test passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_embedded_interface/CMakeLists.txt
index 3081db0b6..742a52ccf 100644
--- a/test/test_model/test_solid_mechanics_model/test_embedded_interface/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/CMakeLists.txt
@@ -1,50 +1,51 @@
#===============================================================================
# @file CMakeLists.txt
#
-# @author Lucas Frérot <lucas.frerot@epfl.ch>
+# @author Lucas Frerot <lucas.frerot@epfl.ch>
#
-# @date creation: Wed Mar 25 2015
-# @date last modification: Wed Mar 25 2015
+# @date creation: Fri Sep 03 2010
+# @date last modification: Thu Jul 09 2015
#
# @brief configuration for embedded interface tests
#
# @section LICENSE
#
-# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
register_test(test_embedded_element_matrix
SOURCES test_embedded_element_matrix.cc
FILES_TO_COPY triangle.msh embedded_element.dat
PACKAGE embedded implicit
)
register_test(test_embedded_interface_model
SOURCES test_embedded_interface_model.cc
FILES_TO_COPY embedded_mesh.msh material.dat matrix
DIRECTORIES_TO_CREATE paraview
PACKAGE embedded implicit
)
register_test(test_embedded_interface_model_prestress
SOURCES test_embedded_interface_model_prestress.cc
FILES_TO_COPY embedded_mesh_prestress.msh embedded_mesh_prestress_reinforcement.msh prestress.dat
PACKAGE embedded implicit
)
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_element_matrix.cc b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_element_matrix.cc
index a292d29b2..b3176dddf 100644
--- a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_element_matrix.cc
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_element_matrix.cc
@@ -1,89 +1,90 @@
/**
- * @file test_embedded_interface_model.cc
+ * @file test_embedded_element_matrix.cc
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date Thu 19 Mar 2015
+ * @date creation: Wed Mar 25 2015
+ * @date last modification: Wed May 13 2015
*
* @brief test of the class EmbeddedInterfaceModel
*
* @section LICENSE
*
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "embedded_interface_model.hh"
using namespace akantu;
int main(int argc, char * argv[]) {
debug::setDebugLevel(dblWarning);
initialize("embedded_element.dat", argc, argv);
const UInt dim = 2;
const Real height = 0.5;
Mesh mesh(dim);
mesh.read("triangle.msh");
Array<Real> nodes_vec(2, dim, "reinforcement_nodes");
nodes_vec.storage()[0] = 0; nodes_vec.storage()[1] = height;
nodes_vec.storage()[2] = 1; nodes_vec.storage()[3] = height;
Array<UInt> conn_vec(1, 2, "reinforcement_connectivity");
conn_vec.storage()[0] = 0; conn_vec.storage()[1] = 1;
Array<std::string> names_vec(1, 1, "reinforcement", "reinforcement_names");
Mesh reinforcement_mesh(dim, "reinforcement_mesh");
reinforcement_mesh.getNodes().copy(nodes_vec);
reinforcement_mesh.addConnectivityType(_segment_2);
reinforcement_mesh.getConnectivity(_segment_2).copy(conn_vec);
reinforcement_mesh.registerData<std::string>("physical_names").alloc(1, 1, _segment_2);
reinforcement_mesh.getData<std::string>("physical_names")(_segment_2).copy(names_vec);
EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
model.initFull(EmbeddedInterfaceModelOptions(_static));
if (model.getInterfaceMesh().getNbElement(_segment_2) != 1)
return EXIT_FAILURE;
if (model.getInterfaceMesh().getSpatialDimension() != 2)
return EXIT_FAILURE;
model.assembleStiffnessMatrix();
SparseMatrix & K = model.getStiffnessMatrix();
Math::setTolerance(1e-8);
// Testing the assembled stiffness matrix
if (!Math::are_float_equal(K(0, 0), 1. - height) ||
!Math::are_float_equal(K(0, 2), height - 1.) ||
!Math::are_float_equal(K(2, 0), height - 1.) ||
!Math::are_float_equal(K(2, 2), 1. - height))
return EXIT_FAILURE;
model.updateResidual();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.cc b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.cc
index befd92f17..26798992c 100644
--- a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.cc
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.cc
@@ -1,105 +1,106 @@
/**
- * @file test_embedded_interface_model.cc
+ * @file test_embedded_interface_model.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date lun. 09 29 16:03:10 2014
+ * @date creation: Wed Mar 25 2015
+ * @date last modification: Thu Jul 09 2015
*
- * @brief Embedded model test based on potential energy
+ * @brief Embedded model test based on potential energy
*
* @section LICENSE
*
- * Copyright (©) 2010-2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <iostream>
#include "aka_common.hh"
#include "embedded_interface_model.hh"
using namespace akantu;
int main (int argc, char * argv[]) {
debug::setDebugLevel(dblWarning);
initialize("material.dat", argc, argv);
UInt dim = 2;
Math::setTolerance(1e-7);
// Mesh here is a 1x1 patch
Mesh mesh(dim);
mesh.read("embedded_mesh.msh");
Array<Real> nodes_vec(2, dim, "reinforcement_nodes");
nodes_vec.storage()[0] = 0; nodes_vec.storage()[1] = 0.5;
nodes_vec.storage()[2] = 1; nodes_vec.storage()[3] = 0.5;
Array<UInt> conn_vec(1, 2, "reinforcement_connectivity");
conn_vec.storage()[0] = 0; conn_vec.storage()[1] = 1;
Array<std::string> names_vec(1, 1, "reinforcement", "reinforcement_names");
Mesh reinforcement_mesh(dim, "reinforcement_mesh");
reinforcement_mesh.getNodes().copy(nodes_vec);
reinforcement_mesh.addConnectivityType(_segment_2);
reinforcement_mesh.getConnectivity(_segment_2).copy(conn_vec);
reinforcement_mesh.registerData<std::string>("physical_names").alloc(1, 1, _segment_2);
reinforcement_mesh.getData<std::string>("physical_names")(_segment_2).copy(names_vec);
EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
model.initFull(EmbeddedInterfaceModelOptions(_static));
Array<Real> & nodes = mesh.getNodes();
Array<Real> & forces = model.getForce();
Array<bool> & bound = model.getBlockedDOFs();
forces(2, 0) = -250;
forces(5, 0) = -500;
forces(8, 0) = -250;
for (UInt i = 0 ; i < mesh.getNbNodes() ; i++) {
if (Math::are_float_equal(nodes(i, 0), 0.))
bound(i, 0) = true;
if (Math::are_float_equal(nodes(i, 1), 0.))
bound(i, 1) = true;
}
model.addDumpFieldVector("displacement");
model.addDumpFieldTensor("stress");
model.setBaseNameToDumper("reinforcement", "reinforcement");
model.addDumpFieldTensorToDumper("reinforcement", "stress_embedded");
// Assemble the global stiffness matrix
model.assembleStiffnessMatrix();
model.updateResidual();
model.getStiffnessMatrix().saveMatrix("matrix_test");
model.solveStatic<_scm_newton_raphson_tangent_not_computed, _scc_residual>(1e-7, 1);
model.updateResidual();
model.dump();
Real pot_energy = model.getEnergy("potential");
if (std::abs(pot_energy - 7.37343e-06) > 1e-5)
return EXIT_FAILURE;
finalize();
return 0;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
index f9eb3e1e2..7f24996e2 100644
--- a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
@@ -1,225 +1,225 @@
/**
- * @file test_embedded_interface_model_prestress.cc
+ * @file test_embedded_interface_model_prestress.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: mar. avril 28 2015
- * @date last modification: mar. avril 28 2015
+ * @date creation: Tue Apr 28 2015
+ * @date last modification: Thu Oct 15 2015
*
- * @brief Embedded model test for prestressing (bases on stress norm)
+ * @brief Embedded model test for prestressing (bases on stress norm)
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "aka_common.hh"
#include "embedded_interface_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
#define YG 0.483644859
#define I_eq 0.012488874
#define A_eq (1e-2 + 1. / 7. * 1.)
/* -------------------------------------------------------------------------- */
struct StressSolution : public BC::Neumann::FromHigherDim {
Real M;
Real I;
Real yg;
Real pre_stress;
StressSolution(UInt dim, Real M, Real I, Real yg = 0, Real pre_stress = 0) :
BC::Neumann::FromHigherDim(Matrix<Real>(dim, dim)),
M(M), I(I), yg(yg), pre_stress(pre_stress)
{}
virtual ~StressSolution() {}
void operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const {
UInt dim = coord.size();
if (dim < 2) AKANTU_DEBUG_ERROR("Solution not valid for 1D");
Matrix<Real> stress(dim, dim); stress.clear();
stress(0, 0) = this->stress(coord(1));
dual.mul<false>(stress, normals);
}
inline Real stress(Real height) const {
return -M / I * (height - yg) + pre_stress;
}
inline Real neutral_axis() const {
return -I * pre_stress / M + yg;
}
};
/* -------------------------------------------------------------------------- */
int main (int argc, char * argv[]) {
initialize("prestress.dat", argc, argv);
debug::setDebugLevel(dblError);
Math::setTolerance(1e-6);
const UInt dim = 2;
/* -------------------------------------------------------------------------- */
Mesh mesh(dim);
mesh.read("embedded_mesh_prestress.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
Mesh reinforcement_mesh(dim, "reinforcement_mesh");
try {
reinforcement_mesh.read("embedded_mesh_prestress_reinforcement.msh");
} catch(debug::Exception & e) {}
reinforcement_mesh.createGroupsFromMeshData<std::string>("physical_names");
EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
model.initFull(EmbeddedInterfaceModelOptions(_static));
/* -------------------------------------------------------------------------- */
/* Computation of analytical residual */
/* -------------------------------------------------------------------------- */
/*
* q = 1000 N/m
* L = 20 m
* a = 1 m
*/
Real steel_area = model.getMaterial("reinforcement").getParam<Real>("area");
Real pre_stress = 1e6;
Real stress_norm = 0.;
StressSolution * concrete_stress = NULL, * steel_stress = NULL;
Real pre_force = pre_stress * steel_area;
Real pre_moment = -pre_force * (YG - 0.25);
Real neutral_axis = YG - I_eq / A_eq * pre_force / pre_moment;
concrete_stress = new StressSolution(dim, pre_moment, 7. * I_eq, YG, -pre_force / (7. * A_eq));
steel_stress = new StressSolution(dim, pre_moment, I_eq, YG, pre_stress - pre_force / A_eq);
stress_norm = std::abs(concrete_stress->stress(1)) * (1 - neutral_axis) * 0.5
+ std::abs(concrete_stress->stress(0)) * neutral_axis * 0.5
+ std::abs(steel_stress->stress(0.25)) * steel_area;
model.applyBC(*concrete_stress, "XBlocked");
ElementGroup & end_node = mesh.getElementGroup("EndNode");
NodeGroup & end_node_group = end_node.getNodeGroup();
NodeGroup::const_node_iterator end_node_it = end_node_group.begin();
Vector<Real> end_node_force = model.getForce().begin(dim)[*end_node_it];
end_node_force(0) += steel_stress->stress(0.25) * steel_area;
Array<Real> analytical_residual(mesh.getNbNodes(), dim, "analytical_residual");
analytical_residual.copy(model.getForce());
model.getForce().clear();
delete concrete_stress;
delete steel_stress;
/* -------------------------------------------------------------------------- */
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "XBlocked");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "YBlocked");
// Assemble the global stiffness matrix
model.assembleStiffnessMatrix();
model.updateResidual();
if (!model.solveStatic<_scm_newton_raphson_tangent_not_computed, _scc_residual>(1e-6, 1))
return EXIT_FAILURE;
model.updateResidual();
/* -------------------------------------------------------------------------- */
/* Computation of FEM residual norm */
/* -------------------------------------------------------------------------- */
ElementGroup & xblocked = mesh.getElementGroup("XBlocked");
NodeGroup & boundary_nodes = xblocked.getNodeGroup();
NodeGroup::const_node_iterator
nodes_it = boundary_nodes.begin(),
nodes_end = boundary_nodes.end();
Array<Real>::vector_iterator com_res = model.getResidual().begin(dim);
Array<Real>::vector_iterator ana_res = analytical_residual.begin(dim);
Array<Real>::vector_iterator position = mesh.getNodes().begin(dim);
Real res_sum = 0.;
UInt lower_node = -1;
UInt upper_node = -1;
Real lower_dist = 1;
Real upper_dist = 1;
for (; nodes_it != nodes_end ; ++nodes_it) {
UInt node_number = *nodes_it;
const Vector<Real> res = com_res[node_number];
const Vector<Real> ana = ana_res[node_number];
const Vector<Real> pos = position[node_number];
if (!Math::are_float_equal(pos(1), 0.25)) {
if ((std::abs(pos(1) - 0.25) < lower_dist) && (pos(1) < 0.25)) {
lower_dist = std::abs(pos(1) - 0.25);
lower_node = node_number;
}
if ((std::abs(pos(1) - 0.25) < upper_dist) && (pos(1) > 0.25)) {
upper_dist = std::abs(pos(1) - 0.25);
upper_node = node_number;
}
}
for (UInt i = 0 ; i < dim ; i++) {
if (!Math::are_float_equal(pos(1), 0.25)) {
res_sum += std::abs(res(i));
}
}
}
const Vector<Real> upper_res = com_res[upper_node], lower_res = com_res[lower_node];
const Vector<Real> end_node_res = com_res[*end_node_it];
Vector<Real> delta = upper_res - lower_res;
delta *= lower_dist / (upper_dist + lower_dist);
Vector<Real> concrete_residual = lower_res + delta;
Vector<Real> steel_residual = end_node_res - concrete_residual;
for (UInt i = 0 ; i < dim ; i++) {
res_sum += std::abs(concrete_residual(i));
res_sum += std::abs(steel_residual(i));
}
Real relative_error = std::abs(res_sum - stress_norm) / stress_norm;
if (relative_error > 1e-3)
return EXIT_FAILURE;
finalize();
return 0;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_material_selector.cc b/test/test_model/test_solid_mechanics_model/test_material_selector.cc
index c082e2ef7..98ecd77a4 100644
--- a/test/test_model/test_solid_mechanics_model/test_material_selector.cc
+++ b/test/test_model/test_solid_mechanics_model/test_material_selector.cc
@@ -1,64 +1,63 @@
/**
- * @file test_material_selector.cc
+ * @file test_material_selector.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri May 01 2015
- * @date last modification: Fri May 01 2015
*
- * @brief Test for material selector
+ * @brief Test for material selector
*
* @section LICENSE
*
- * Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include "aka_common.hh"
#include "solid_mechanics_model.hh"
using namespace akantu;
int main(int argc, char * argv[]) {
initialize("material_selector.dat", argc, argv);
Math::setTolerance(1e-8);
Mesh mesh(1);
mesh.read("material_selector.msh");
SolidMechanicsModel model(mesh);
MeshDataMaterialSelector<std::string> selector("physical_names", model);
model.setMaterialSelector(selector);
model.initFull();
Material & chocolate = model.getMaterial("chocolate");
Material & chewing_gum = model.getMaterial("chewing-gum");
Material & candy = model.getMaterial("candy");
UInt chocolate_element = chocolate.getElementFilter(_segment_2)(0, 0);
UInt chewing_gum_element = chewing_gum.getElementFilter(_segment_2)(0, 0);
UInt candy_element = candy.getElementFilter(_segment_2)(0, 0);
if (chocolate_element != 0 ||
chewing_gum_element != 1 ||
candy_element != 2)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_materials/CMakeLists.txt
index cabf83ffb..5f2820fa8 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_materials/CMakeLists.txt
@@ -1,81 +1,82 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
-# @date creation: Fri Nov 26 2010
-# @date last modification: Fri Feb 14 2014
+# @date creation: Fri Oct 22 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for materials tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_local_material_barre_trou_mesh barre_trou.geo 2 2)
add_mesh(test_local_material_barre_trou_mesh mesh_section_gap.geo 2 2)
register_test(test_local_material
SOURCES test_local_material.cc local_material_damage.cc
EXTRA_FILES local_material_damage.hh local_material_damage_inline_impl.cc
DEPENDS test_local_material_barre_trou_mesh
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE core
)
add_mesh(test_material_thermal_mesh square.geo 2 1)
register_test(test_material_thermal
SOURCES test_material_thermal.cc
DEPENDS test_material_thermal_mesh
FILES_TO_COPY material_thermal.dat
PACKAGE core
)
# ==============================================================================
add_mesh(test_interpolate_stress_mesh interpolation.geo 3 2)
register_test(test_interpolate_stress test_interpolate_stress.cc
FILES_TO_COPY material.dat
DEPENDS test_interpolate_stress_mesh
DIRECTORIES_TO_CREATE paraview
PACKAGE lapack core
)
#===============================================================================
add_mesh(test_material_orthotropic_square_mesh square.geo 2 1)
register_test(test_material_orthotropic
SOURCES test_material_orthotropic.cc
DEPENDS test_material_orthotropic_square_mesh
FILES_TO_COPY orthotropic.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE core
)
#===============================================================================
register_test(test_material_mazars
SOURCES test_material_mazars.cc
FILES_TO_COPY material_mazars.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE core
)
# ==============================================================================
add_akantu_test(test_material_viscoelastic "test the visco elastic materials")
add_akantu_test(test_material_non_local "test the non-local materials")
add_akantu_test(test_material_elasto_plastic_linear_isotropic_hardening "test the elasto plastic with linear isotropic hardening materials")
\ No newline at end of file
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.cc b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.cc
index ee1c0b53d..7ed5bafaa 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.cc
@@ -1,106 +1,107 @@
/**
* @file local_material_damage.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Nov 26 2010
- * @date last modification: Tue Jun 24 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the material class for the damage material
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "local_material_damage.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
LocalMaterialDamage::LocalMaterialDamage(SolidMechanicsModel & model,
const ID & id) :
Material(model, id),
damage("damage", *this) {
AKANTU_DEBUG_IN();
this->registerParam("E" , E , 0. , _pat_parsable, "Young's modulus" );
this->registerParam("nu" , nu , 0.5 , _pat_parsable, "Poisson's ratio" );
this->registerParam("lambda" , lambda , _pat_readable, "First Lamé coefficient" );
this->registerParam("mu" , mu , _pat_readable, "Second Lamé coefficient");
this->registerParam("kapa" , kpa , _pat_readable, "Bulk coefficient" );
this->registerParam("Yd" , Yd , 50., _pat_parsmod);
this->registerParam("Sd" , Sd , 5000., _pat_parsmod);
damage.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void LocalMaterialDamage::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
lambda = nu * E / ((1 + nu) * (1 - 2*nu));
mu = E / (2 * (1 + nu));
kpa = lambda + 2./3. * mu;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void LocalMaterialDamage::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = damage(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeStressOnQuad(grad_u, sigma, *dam);
++dam;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void LocalMaterialDamage::computePotentialEnergy(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Material::computePotentialEnergy(el_type, ghost_type);
if(ghost_type != _not_ghost) return;
Real * epot = potential_energy(el_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computePotentialEnergyOnQuad(grad_u, sigma, *epot);
epot++;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.hh b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.hh
index dabfcdae3..e042070a9 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.hh
+++ b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.hh
@@ -1,128 +1,129 @@
/**
* @file local_material_damage.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Nov 26 2010
- * @date last modification: Fri May 16 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Material isotropic elastic
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__
#define __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__
__BEGIN_AKANTU__
class LocalMaterialDamage : public Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
LocalMaterialDamage(SolidMechanicsModel & model, const ID & id = "");
virtual ~LocalMaterialDamage() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void initMaterial();
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// constitutive law for a given quadrature point
inline void computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & damage);
/// compute tangent stiffness
virtual void computeTangentStiffness(__attribute__ ((unused)) const ElementType & el_type,
__attribute__ ((unused)) Array<Real> & tangent_matrix,
__attribute__ ((unused)) GhostType ghost_type = _not_ghost) {};
/// compute the potential energy for all elements
void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost);
/// compute the potential energy for on element
inline void computePotentialEnergyOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & epot);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// compute the celerity of wave in the material
inline Real getCelerity(const Element & element) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real);
private:
/// the young modulus
Real E;
/// Poisson coefficient
Real nu;
/// First Lamé coefficient
Real lambda;
/// Second Lamé coefficient (shear modulus)
Real mu;
/// resistance to damage
Real Yd;
/// damage threshold
Real Sd;
/// Bulk modulus
Real kpa;
/// damage internal variable
InternalField<Real> damage;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "local_material_damage_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__ */
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage_inline_impl.cc b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage_inline_impl.cc
index 2d8d5ccf0..6459209fe 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage_inline_impl.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage_inline_impl.cc
@@ -1,80 +1,81 @@
/**
* @file local_material_damage_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Nov 26 2010
- * @date last modification: Fri May 16 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the inline functions of the material damage
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
inline void LocalMaterialDamage::computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & dam) {
Real trace = grad_u.trace();
/// \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla u_{ij} + \nabla u_{ji})
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
sigma(i, j) = (i == j)*lambda*trace + mu*(grad_u(i, j) + grad_u(j, i));
}
}
Real Y = 0;
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
Y += sigma(i,j) * grad_u(i,j);
}
}
Y *= 0.5;
Real Fd = Y - Yd - Sd*dam;
if (Fd > 0) dam = (Y - Yd) / Sd;
dam = std::min(dam,1.);
sigma *= 1-dam;
}
/* -------------------------------------------------------------------------- */
inline void LocalMaterialDamage::computePotentialEnergyOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & sigma,
Real & epot) {
epot = 0.;
for (UInt i = 0, t = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j, ++t)
epot += sigma(i, j) * (grad_u(i, j) - (i == j));
epot *= .5;
}
/* -------------------------------------------------------------------------- */
inline Real LocalMaterialDamage::getCelerity(__attribute__ ((unused)) const Element & element) const {
return (std::sqrt(E/rho));
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc
index 6e9b1861f..e940f3342 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc
@@ -1,183 +1,184 @@
/**
* @file test_interpolate_stress.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Thu Jun 07 2012
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Test for the stress interpolation function
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
Real function(Real x, Real y, Real z) {
return 100. + 2. * x + 3. * y + 4 * z;
}
int main(int argc, char *argv[]) {
initialize("../material.dat", argc, argv);
debug::setDebugLevel(dblWarning);
const UInt spatial_dimension = 3;
const ElementType type = _tetrahedron_10;
Mesh mesh(spatial_dimension);
mesh.read("interpolation.msh");
const ElementType type_facet = mesh.getFacetType(type);
Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
MeshUtils::buildAllFacets(mesh, mesh_facets);
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
Array<Real> & position = mesh.getNodes();
UInt nb_facet = mesh_facets.getNbElement(type_facet);
UInt nb_element = mesh.getNbElement(type);
/// compute quadrature points positions on facets
typedef FEEngineTemplate<IntegratorGauss,ShapeLagrange> MyFEEngineType;
model.registerFEEngineObject<MyFEEngineType>("FacetsFEEngine", mesh_facets, spatial_dimension-1);
model.getFEEngine("FacetsFEEngine").initShapeFunctions();
UInt nb_quad_per_facet = model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
UInt nb_tot_quad = nb_quad_per_facet * nb_facet;
Array<Real> quad_facets(nb_tot_quad, spatial_dimension);
model.getFEEngine("FacetsFEEngine").interpolateOnIntegrationPoints(position,
quad_facets,
spatial_dimension,
type_facet);
Array<Element> & facet_to_element = mesh_facets.getSubelementToElement(type);
UInt nb_facet_per_elem = facet_to_element.getNbComponent();
ElementTypeMapArray<Real> element_quad_facet;
element_quad_facet.alloc(nb_element * nb_facet_per_elem * nb_quad_per_facet,
spatial_dimension,
type);
ElementTypeMapArray<Real> interpolated_stress("interpolated_stress", "");
mesh.initElementTypeMapArray(interpolated_stress,
spatial_dimension * spatial_dimension,
spatial_dimension);
Array<Real> & interp_stress = interpolated_stress(type);
interp_stress.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet);
Array<Real> & el_q_facet = element_quad_facet(type);
for (UInt el = 0; el < nb_element; ++el) {
for (UInt f = 0; f < nb_facet_per_elem; ++f) {
UInt global_facet = facet_to_element(el, f).element;
for (UInt q = 0; q < nb_quad_per_facet; ++q) {
for (UInt s = 0; s < spatial_dimension; ++s) {
el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet
+ f * nb_quad_per_facet + q, s)
= quad_facets(global_facet * nb_quad_per_facet + q, s);
}
}
}
}
/// compute quadrature points position of the elements
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
UInt nb_tot_quad_el = nb_quad_per_element * nb_element;
Array<Real> quad_elements(nb_tot_quad_el, spatial_dimension);
model.getFEEngine().interpolateOnIntegrationPoints(position,
quad_elements,
spatial_dimension,
type);
/// assign some values to stresses
Array<Real> & stress
= const_cast<Array<Real>&>(model.getMaterial(0).getStress(type));
for (UInt q = 0; q < nb_tot_quad_el; ++q) {
for (UInt s = 0; s < spatial_dimension * spatial_dimension; ++s) {
stress(q, s) = s * function(quad_elements(q, 0),
quad_elements(q, 1),
quad_elements(q, 2));
}
}
/// interpolate stresses on facets' quadrature points
model.getMaterial(0).initElementalFieldInterpolation(element_quad_facet);
model.getMaterial(0).interpolateStress(interpolated_stress);
Real tolerance = 1.e-10;
/// check results
for (UInt el = 0; el < nb_element; ++el) {
for (UInt f = 0; f < nb_facet_per_elem; ++f) {
for (UInt q = 0; q < nb_quad_per_facet; ++q) {
for (UInt s = 0; s < spatial_dimension * spatial_dimension; ++s) {
Real x = el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet
+ f * nb_quad_per_facet + q, 0);
Real y = el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet
+ f * nb_quad_per_facet + q, 1);
Real z = el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet
+ f * nb_quad_per_facet + q, 2);
Real theoretical = s * function(x, y, z);
Real numerical = interp_stress(el * nb_facet_per_elem * nb_quad_per_facet
+ f * nb_quad_per_facet + q, s);
if (std::abs(theoretical - numerical) > tolerance) {
std::cout << "Theoretical and numerical values aren't coincident!" << std::endl;
return EXIT_FAILURE;
}
}
}
}
}
std::cout << "OK: Stress interpolation test passed." << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_local_material.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_local_material.cc
index cc6850bdd..0985f4850 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_local_material.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_local_material.cc
@@ -1,138 +1,139 @@
/**
* @file test_local_material.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
- * @author Clement Roux-Langlois <clement.roux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
- * @date creation: Fri Nov 26 2010
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief test of the class SolidMechanicsModel with custom local damage on a
- * notched plate
+ * notched plate
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "local_material_damage.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
UInt max_steps = 1100;
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("mesh_section_gap.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass, true));
model.registerNewCustomMaterials<LocalMaterialDamage>("local_damage");
model.initMaterials();
Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step/2.5);
model.assembleMassLumped();
std::cout << model << std::endl;
/// Dirichlet boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed");
// model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed");
// Boundary condition (Neumann)
Matrix<Real> stress(2,2);
stress.eye(7e5);
model.applyBC(BC::Neumann::FromHigherDim(stress), "Traction");
/*model.setBaseName("damage_local");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("damage" );
model.addDumpField("stress" );
model.addDumpField("strain" );
model.dump();*/
for(UInt s = 0; s < max_steps; ++s) {
if(s < 100){
// Boundary condition (Neumann)
stress.eye(7e5);
model.applyBC(BC::Neumann::FromHigherDim(stress), "Traction");
}
model.solveStep();
/*epot = model.getPotentialEnergy();
ekin = model.getKineticEnergy();
if(s % 10 == 0) std::cout << s << " " << epot << " " << ekin << " " << epot + ekin
<< std::endl;
if(s % 10 == 0) std::cout << "Step " << s+1 << "/" << max_steps <<std::endl;
if(s % 10 == 0) model.dump();*/
}
const Vector<Real> & lower_bounds = mesh.getLowerBounds();
const Vector<Real> & upper_bounds = mesh.getUpperBounds();
Real L = upper_bounds(0) - lower_bounds(0);
const ElementTypeMapArray<UInt> & filter = model.getMaterial(0).getElementFilter();
ElementTypeMapArray<UInt>::type_iterator it = filter.firstType(spatial_dimension);
ElementTypeMapArray<UInt>::type_iterator end = filter.lastType(spatial_dimension);
Vector<Real> barycenter(spatial_dimension);
bool is_fully_damaged = false;
for(; it != end; ++it) {
UInt nb_elem = mesh.getNbElement(*it);
const UInt nb_gp = model.getFEEngine().getNbIntegrationPoints(*it);
Array<Real> & material_damage_array = model.getMaterial(0).getArray<Real>("damage", *it);
UInt cpt = 0;
for(UInt nel = 0; nel < nb_elem ; ++nel){
if (material_damage_array(cpt,0) > 0.9){
is_fully_damaged = true;
mesh.getBarycenter(nel,*it,barycenter.storage());
if( (std::abs(barycenter(0)-(L/2)) < (L/10) ) ) {
return EXIT_FAILURE;
}
}
cpt += nb_gp;
}
}
if(!is_fully_damaged)
return EXIT_FAILURE;
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/CMakeLists.txt
index 53d6d8db0..6ee31ab1a 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/CMakeLists.txt
@@ -1,45 +1,47 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Jaehyun Cho <jaehyun.cho@epfl.ch>
#
-# @date creation: Fri Aug 3 2015
+# @date creation: Fri Oct 22 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief test for material type elasto plastic linear isotropic hardening using
-# tension-compression test
+# tension-compression test
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_material_standard_linear_isotropic_hardening_mesh
test_material_elasto_plastic_linear_isotropic_hardening.geo 3 2)
register_test(test_material_standard_linear_isotropic_hardening
SOURCES test_material_elasto_plastic_linear_isotropic_hardening.cc
DEPENDS test_material_standard_linear_isotropic_hardening_mesh
FILES_TO_COPY test_material_elasto_plastic_linear_isotropic_hardening.dat
PACKAGE core
)
#===============================================================================
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 ac16544f3..4d775351e 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,127 +1,127 @@
/**
* @file test_material_elasto_plastic_linear_isotropic_hardening.cc
*
- # @author Jaehyun Cho <jaehyun.cho@epfl.ch>
+ * @author Jaehyun Cho <jaehyun.cho@epfl.ch>
*
- # @date creation: Fri Aug 3 2015
+ * @date creation: Thu Dec 03 2015
*
- # @brief test for material type elasto plastic linear isotropic hardening using
- # tension-compression test
+ * @brief test for material type elasto plastic linear isotropic hardening using
+ * # tension-compression test
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include <iostream>
using namespace akantu;
// /* -------------------------------------------------------------------------- */
const UInt spatial_dimension = 2;
const Real time_step = 1e-4;
const Real max_time = 0.15;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
initialize("test_material_elasto_plastic_linear_isotropic_hardening.dat", argc, argv);
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
MeshPartition * partition = NULL;
if(prank == 0) {
mesh.read("test_material_elasto_plastic_linear_isotropic_hardening.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
SolidMechanicsModel model(mesh);
model.initParallel(partition);
mesh.createGroupsFromMeshData<std::string>("physical_names");
/// model initialization
model.initFull(SolidMechanicsModelOptions(_implicit_dynamic));
Material &mat = model.getMaterial(0);
Real E = mat.getParam<Real>("E");
Real rho = mat.getParam<Real>("rho");
Real h = mat.getParam<Real>("h");
Real sigma_y = mat.getParam<Real>("sigma_y");
mat.setParam("E", E);
mat.setParam("rho", rho);
mat.setParam("h", h);
mat.setParam("sigma_y", sigma_y);
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "left");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "bottom");
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator lastType = mesh.lastType(spatial_dimension);
model.setBaseName("dynamic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("stress" );
model.addDumpField("strain" );
model.dump();
std::ofstream output2;
output2.open("strain-stress.txt");
if(!output2.good()) AKANTU_DEBUG_ERROR("Cannot open file \"strain-stress.txt\"");
output2 << "timestep, strain(0), stress(0)" << std::endl;
output2 << "0 0.0 0.0 " << std::endl;
model.setTimeStep(time_step);
double dz = 1e-4;
Real time = 0.;
ElementTypeMapArray<Real> & byel_stress = model.flattenInternal("stress", _ek_regular);
for (UInt s = 1; time < max_time; ++s, time += time_step) {
if(prank == 0)
std::cout << "Traction by " << dz*s << " \r" << std::flush;
model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-12, 100);
model.applyBC(BC::Dirichlet::IncrementValue(dz, _x), "right");
if(s % 10 == 0){
model.dump();
Real strainxx = 0.0;
Real stressxx = 0.0;
for(it = mesh.firstType(spatial_dimension); it != lastType; ++it){
Array<Real> & stress = byel_stress(*it);
for(UInt quad = 0; quad < stress.getSize(); ++quad){
stressxx += stress(quad,0);
}
strainxx = dz*s/10.0;
stressxx = stressxx/stress.getSize();
output2 << s << " " << strainxx << " " << stressxx << std::endl;
}
}
}
output2.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_mazars.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_mazars.cc
index a74ad2b74..047865d5a 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_mazars.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_mazars.cc
@@ -1,304 +1,307 @@
/**
- * @file tes_material_mazars.cc
- * @author Clement Roux-Langlois <clement.roux@epfl.ch>
- * @date Fri Sep 11 20151
+ * @file test_material_mazars.cc
*
- * @brief test for material mazars, dissymmetric
+ * @author Clement Roux <clement.roux@epfl.ch>
+ *
+ * @date creation: Thu Oct 08 2015
+ * @date last modification: Tue Dec 08 2015
+ *
+ * @brief test for material mazars, dissymmetric
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "solid_mechanics_model.hh"
#include "material.hh"
//#include "io_helper_tools.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
debug::setDebugLevel(akantu::dblWarning);
akantu::initialize("material_mazars.dat", argc, argv);
const UInt spatial_dimension = 3;
// ElementType type = _quadrangle_4;
ElementType type = _hexahedron_8;
// UInt compression_steps = 5e5;
// Real max_compression = 0.01;
// UInt traction_steps = 1e4;
// Real max_traction = 0.001;
Mesh mesh(spatial_dimension);
mesh.addConnectivityType(type);
Array<Real> & nodes = const_cast<Array<Real> &>(mesh.getNodes());
Array<UInt> & connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(type));
const Real width = 1;
UInt nb_dof = 0;
connectivity.resize(1);
if(type == _hexahedron_8) {
nb_dof = 8;
nodes.resize(nb_dof);
nodes(0,0) = 0.;
nodes(0,1) = 0.;
nodes(0,2) = 0.;
nodes(1,0) = width;
nodes(1,1) = 0.;
nodes(1,2) = 0.;
nodes(2,0) = width;
nodes(2,1) = width;
nodes(2,2) = 0;
nodes(3,0) = 0;
nodes(3,1) = width;
nodes(3,2) = 0;
nodes(4,0) = 0.;
nodes(4,1) = 0.;
nodes(4,2) = width;
nodes(5,0) = width;
nodes(5,1) = 0.;
nodes(5,2) = width;
nodes(6,0) = width;
nodes(6,1) = width;
nodes(6,2) = width;
nodes(7,0) = 0;
nodes(7,1) = width;
nodes(7,2) = width;
connectivity(0,0) = 0;
connectivity(0,1) = 1;
connectivity(0,2) = 2;
connectivity(0,3) = 3;
connectivity(0,4) = 4;
connectivity(0,5) = 5;
connectivity(0,6) = 6;
connectivity(0,7) = 7;
} else if (type == _quadrangle_4) {
nb_dof = 4;
nodes.resize(nb_dof);
nodes(0,0) = 0.;
nodes(0,1) = 0.;
nodes(1,0) = width;
nodes(1,1) = 0;
nodes(2,0) = width;
nodes(2,1) = width;
nodes(3,0) = 0.;
nodes(3,1) = width;
connectivity(0,0) = 0;
connectivity(0,1) = 1;
connectivity(0,2) = 2;
connectivity(0,3) = 3;
}
SolidMechanicsModel model(mesh);
model.initFull();
Material & mat = model.getMaterial(0);
std::cout << mat << std::endl;
/// boundary conditions
Array<Real> & disp = model.getDisplacement();
Array<Real> & velo = model.getVelocity();
Array<bool> & boun = model.getBlockedDOFs();
for (UInt i = 0; i < nb_dof; ++i) {
boun(i,0) = true;
}
// boun(0,1) = true;
// boun(1,1) = true;
// boun(2,1) = true;
// boun(0,2) = true;
// boun(1,2) = true;
// boun(2,2) = true;
// disp(1,0) = 0;
// forc(1,0) = atof(argv[2]);
// velo(0,0) = -atof(argv[2]);
// velo(1,0) = atof(argv[2]);
model.assembleMassLumped();
Real time_step = model.getStableTimeStep() * .5;
//Real time_step = 1e-5;
std::cout << "Time Step = " << time_step << "s - nb elements : " << mesh.getNbElement(type) << std::endl;
model.setTimeStep(time_step);
model.updateResidual();
std::ofstream energy;
energy.open("energies_and_scalar_mazars.csv");
energy << "id,rtime,epot,ekin,u,wext,kin+pot,D,strain_xx,strain_yy,stress_xx,stress_yy,edis,tot" << std::endl;
/// Set dumper
model.setBaseName("uniaxial_comp-trac_mazars");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("damage" );
model.addDumpField("strain" );
model.addDumpField("stress" );
model.addDumpField("partitions" );
model.dump();
const Array<Real> & strain = mat.getGradU(type);
const Array<Real> & stress = mat.getStress(type);
const Array<Real> & damage = mat.getArray<Real>("damage", type);
/* ------------------------------------------------------------------------ */
/* Main loop */
/* ------------------------------------------------------------------------ */
Real wext = 0.;
Real sigma_max=0, sigma_min=0;
Real max_disp;
Real stress_xx_compression_1;
UInt nb_steps = 7e5/150;
Real adisp = 0;
for(UInt s = 0; s < nb_steps; ++s) {
if(s == 0) {
max_disp = 0.003;
adisp = -(max_disp * 8./nb_steps) /2.;
std::cout << "Step " << s << " compression: " << max_disp <<std::endl;
}
if(s == (2*nb_steps / 8)) {
stress_xx_compression_1 = stress(0,0);
max_disp = 0+max_disp;
adisp = max_disp * 8./nb_steps;
std::cout << "Step " << s << " discharge" << std::endl;
}
if(s == (3*nb_steps / 8)) {
max_disp = 0.004;
adisp = - max_disp * 8./nb_steps;
std::cout << "Step " << s << " compression: " << max_disp <<std::endl;
}
if(s == (4*nb_steps / 8)) {
if(stress(0,0)<stress_xx_compression_1){
std::cout << "after this second compression step softening should have started"
<< std::endl;
return EXIT_FAILURE;
}
max_disp = 0.0015+max_disp;
adisp = max_disp * 8./nb_steps;
std::cout << "Step " << s << " discharge tension: " << max_disp <<std::endl;
}
if(s == (5*nb_steps / 8)) {
max_disp = 0.+0.0005;
adisp = - max_disp * 8./nb_steps;
std::cout << "Step " << s << " discharge" << std::endl;
}
if(s == (6*nb_steps / 8)) {
max_disp = 0.0035-0.001;
adisp = max_disp * 8./nb_steps;
std::cout << "Step " << s << " tension: " << max_disp <<std::endl;
}
if(s == (7*nb_steps / 8)) {
//max_disp = max_disp;
adisp = - max_disp * 8./nb_steps;
std::cout << "Step " << s << " discharge" << std::endl;
}
for (UInt i = 0; i < nb_dof; ++i) {
if(std::abs(nodes(i,0) - width) < std::numeric_limits<Real>::epsilon()) {
disp(i,0) += adisp;
velo(i,0) = adisp / time_step;
}
}
std::cout << "S: " << s << "/" << nb_steps << " inc disp: " << adisp << " disp: " << std::setw(5) << disp(2,0) << "\r" << std::flush;
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
Real epot = model.getEnergy("potential");
Real ekin = model.getEnergy("kinetic");
Real edis = model.getEnergy("dissipated");
wext += model.getEnergy("external work");
/*for (UInt i = 0; i < nb_dof; ++i) {
wext += boun(i,0) * forc(i,0) * velo(i,0) * time_step;
}*/
sigma_max = std::max(sigma_max,stress(0,0));
sigma_min = std::min(sigma_min,stress(0,0));
if(s % 10 == 0)
energy << s << "," // 1
<< s*time_step << "," // 2
<< epot << "," // 3
<< ekin << "," // 4
<< disp(2,0) << "," // 5
<< wext << "," // 6
<< epot + ekin << "," // 7
<< damage(0) << "," // 8
<< strain(0,0) << "," // 9
<< strain(0,3) << "," // 11
<< stress(0,0) << "," // 10
<< stress(0,3) << "," // 10
<< edis << "," // 12
<< epot + ekin + edis // 13
<< std::endl;
if(s % 100 == 0)
model.dump();
}
std::cout << std::endl << "sigma_max = " << sigma_max << ", sigma_min = " << sigma_min << std::endl;
/// Verif the maximal/minimal stress values
if( (std::abs(sigma_max)>std::abs(sigma_min)) || (std::abs(sigma_max-6.24e6)>1e5)
|| (std::abs(sigma_min+2.943e7)>1e6) )
return EXIT_FAILURE;
energy.close();
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/CMakeLists.txt
index 6302ed999..f807bd4ec 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/CMakeLists.txt
@@ -1,50 +1,52 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
+# @author Clement Roux <clement.roux@epfl.ch>
#
-# @date creation: Mon Jan 20 2014
-# @date last modification: Mon Jan 20 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for materials tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_material_non_local_mesh mesh.geo 2 1 OUTPUT mesh.msh)
add_mesh(test_material_damage_non_local_mesh mesh_section_gap.geo 2 1 OUTPUT mesh_section_gap.msh)
register_test(test_material_damage_non_local
SOURCES test_material_damage_non_local.cc
DEPENDS test_material_damage_non_local_mesh
FILES_TO_COPY material_damage_non_local.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE damage_non_local
)
register_test(test_material_non_local
SOURCES test_material_non_local.cc custom_non_local_test_material.cc
DEPENDS test_material_non_local_mesh
FILES_TO_COPY material.dat
PACKAGE damage_non_local
)
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc
index 11e8811b6..531f5ff43 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc
@@ -1,88 +1,89 @@
/**
* @file custom_non_local_test_material.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
- * @date Sun Mar 1 15:57:50 2015
+ * @date creation: Sun Mar 01 2015
+ * @date last modification: Thu Oct 15 2015
*
* @brief Custom material to test the non local implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "custom_non_local_test_material.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt dim>
CustomNonLocalTestMaterial<dim>::CustomNonLocalTestMaterial(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
MyElasticParent(model, id),
MyNonLocalParent(model, id),
local_damage("local_damage", *this),
damage("damage", *this)
{
// Initialize the internal field by specifying the number of components
this->local_damage.initialize(1);
this->damage.initialize(1);
/// register the non-local variable in the manager
this->model->getNonLocalManager().registerNonLocalVariable(this->local_damage.getName(), this->damage.getName(), 1);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void CustomNonLocalTestMaterial<dim>::initMaterial() {
MyElasticParent::initMaterial();
MyNonLocalParent::initMaterial();
this->model->getNonLocalManager().nonLocalVariableToNeighborhood(damage.getName(), this->name);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void CustomNonLocalTestMaterial<dim>::computeStress(ElementType el_type, GhostType ghost_type) {
MyElasticParent::computeStress(el_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void CustomNonLocalTestMaterial<dim>::computeNonLocalStress(ElementType el_type, GhostType ghost_type) {
Array<Real>::const_scalar_iterator dam = this->damage(el_type, ghost_type).begin();
Array<Real>::matrix_iterator stress = this->stress(el_type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator stress_end = this->stress(el_type, ghost_type).end(dim, dim);
// compute the damage and update the stresses
for (; stress != stress_end; ++stress, ++dam) {
*stress *= (1. - *dam);
}
}
/* -------------------------------------------------------------------------- */
// Instantiate the material for the 3 dimensions
INSTANTIATE_MATERIAL(CustomNonLocalTestMaterial);
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
index 073cb5f37..2c0bf96cc 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
@@ -1,101 +1,103 @@
/**
- * @file custom_non_local_test_material.cc
+ * @file custom_non_local_test_material.hh
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
- * @date Sun Mar 1 15:57:50 2015
+ * @date creation: Thu Aug 23 2012
+ * @date last modification: Thu Oct 15 2015
*
* @brief Custom material to test the non local implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "material_non_local.hh"
#include "material_elastic.hh"
#ifndef __CUSTOM_NON_LOCAL_TEST_MATERIAL_HH__
#define __CUSTOM_NON_LOCAL_TEST_MATERIAL_HH__
__BEGIN_AKANTU__
template<UInt dim>
class CustomNonLocalTestMaterial : public MaterialElastic<dim>,
public MaterialNonLocal<dim> {
public:
typedef MaterialNonLocal<dim> MyNonLocalParent;
typedef MaterialElastic<dim> MyElasticParent;
CustomNonLocalTestMaterial(SolidMechanicsModel & model, const ID & id);
/* ------------------------------------------------------------------------ */
virtual void initMaterial();
void computeNonLocalStress(ElementType el_type, GhostType ghost_type);
void computeStress(ElementType el_type, GhostType ghost_type);
protected:
/* ------------------------------------------------------------------------ */
void computeNonLocalStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(dim, ghost_type);
Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(dim, ghost_type);
for(; it != last_type; ++it) {
computeNonLocalStress(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
public:
/* ------------------------------------------------------------------------ */
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
return MyNonLocalParent::getNbDataForElements(elements, tag) +
MyElasticParent::getNbDataForElements(elements, tag);
}
virtual inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
MyNonLocalParent::packElementData(buffer, elements, tag);
MyElasticParent::packElementData(buffer, elements, tag);
}
virtual inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
MyNonLocalParent::unpackElementData(buffer, elements, tag);
MyElasticParent::unpackElementData(buffer, elements, tag);
}
void setDamage(Real dam) {
this->local_damage.setDefaultValue(dam);
}
protected:
InternalField<Real> local_damage;
InternalField<Real> damage;
};
__END_AKANTU__
#endif /* __CUSTOM_NON_LOCAL_TEST_MATERIAL_HH__ */
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local.cc
index 7e3f92d06..3e2f2f4dc 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local.cc
@@ -1,125 +1,126 @@
/**
* @file test_material_damage_non_local.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Clément Roux-Langlois <clement.roux@epfl.ch>
+ * @author Clement Roux <clement.roux@epfl.ch>
*
- * @date creation: Tue Sep 13 2011
- * @date last modification: Thu Apr 03 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Thu Oct 15 2015
*
- * @brief test for non-local damage materials on a 2D plate with a section gap
- * the sample should break at the notch
+ * @brief test for non-local damage materials on a 2D plate with a section gap
+ * the sample should break at the notch
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[])
{
debug::setDebugLevel(dblWarning);
akantu::initialize("material_damage_non_local.dat", argc, argv);
UInt max_steps = 1100;
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("mesh_section_gap.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step/2.5);
std::cout << model << std::endl;
model.applyBC(BC::Dirichlet::FixedValue(0.0), "Fixed");
// Boundary condition (Neumann)
Matrix<Real> stress(2,2);
stress.eye(5e8);
model.applyBC(BC::Neumann::FromHigherDim(stress), "Traction");
/*model.setBaseName("damage_non_local");
model.addDumpFieldVector("displacement");
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("damage" );
model.addDumpField("stress" );
model.addDumpField("strain" );
model.dump();*/
for(UInt s = 0; s < max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
//if(s % 100 == 0) std::cout << "Step " << s+1 << "/" << max_steps <<std::endl;
//if(s % 100 == 0) model.dump();
}
const Vector<Real> & lower_bounds = mesh.getLowerBounds();
const Vector<Real> & upper_bounds = mesh.getUpperBounds();
Real L = upper_bounds(0) - lower_bounds(0);
Real H = upper_bounds(1) - lower_bounds(1);
const ElementTypeMapArray<UInt> & filter = model.getMaterial(0).getElementFilter();
ElementTypeMapArray<UInt>::type_iterator it = filter.firstType(spatial_dimension);
ElementTypeMapArray<UInt>::type_iterator end = filter.lastType(spatial_dimension);
Vector<Real> barycenter(spatial_dimension);
for(; it != end; ++it) {
UInt nb_elem = mesh.getNbElement(*it);
const UInt nb_gp = model.getFEEngine().getNbIntegrationPoints(*it);
Array<Real> & material_damage_array = model.getMaterial(0).getArray<Real>("damage", *it);
UInt cpt = 0;
for(UInt nel = 0; nel < nb_elem ; ++nel){
mesh.getBarycenter(nel,*it,barycenter.storage());
if( (std::abs(barycenter(0)-(L/2)+0.025)<0.025)
&& (std::abs(barycenter(1)-(H/2)+0.025)<0.025) ) {
if (material_damage_array(cpt,0) < 0.9){
// std::cout << "barycenter(0) = " << barycenter(0) << ", barycenter(1) = "
// << barycenter(1) <<std::endl;
return EXIT_FAILURE;
}
}
cpt += nb_gp;
}
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_non_local.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_non_local.cc
index 366c3cf11..5ab8de4de 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_non_local.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_non_local.cc
@@ -1,107 +1,110 @@
/**
* @file test_material_non_local.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date Wed Aug 31 11:09:48 2011
+ * @date creation: Wed Aug 31 2011
+ * @date last modification: Thu Oct 15 2015
*
* @brief test of the main part of the non local materials
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "solid_mechanics_model.hh"
#include "custom_non_local_test_material.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize("material.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
// mesh creation and read
MeshPartition * partition;
if(prank == 0) {
mesh.read("mesh.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
} else {
partition = NULL;
}
/// model creation
SolidMechanicsModel model(mesh);
model.initParallel(partition);
delete partition;
/// model initialization changed to use our material
model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass, true));
model.registerNewCustomMaterials< CustomNonLocalTestMaterial<spatial_dimension> >("custom_non_local_test_material");
model.initMaterials();
CustomNonLocalTestMaterial<spatial_dimension> & mat = dynamic_cast<CustomNonLocalTestMaterial<spatial_dimension> &>(model.getMaterial("test"));
if(prank == 0) std::cout << mat << std::endl;
// Setting up the dumpers + first dump
model.setBaseName("non_local_material");
model.addDumpFieldVector("displacement");
model.addDumpFieldVector("force" );
model.addDumpField("partitions" );
model.addDumpField("stress" );
model.addDumpField("stress" );
model.addDumpField("local_damage");
model.addDumpField("damage" );
model.updateResidual();
model.dump();
//Array<Real> & damage = mat.getArray("local_damage", _quadrangle_4);
Array<Real> & damage = mat.getArray<Real>("local_damage", _triangle_3);
RandGenerator<UInt> gen;
for (UInt i = 0; i < 1; ++i) {
UInt g = (gen() / Real(RandGenerator<UInt>::max() - RandGenerator<UInt>::min())) * damage.getSize();
std::cout << prank << " -> " << g << std::endl;
damage(g) = 1.;
}
model.updateResidual();
model.dump();
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc
index 5f53d0d36..b977ae637 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc
@@ -1,103 +1,104 @@
/**
- * @file test_solid_mechanics_model_square.cc
+ * @file test_material_orthotropic.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Sep 22 2010
- * @date last modification: Fri Apr 04 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Tue Sep 01 2015
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
// akantu::initialize("orthotropic.dat", argc, argv);
akantu::initialize("orthotropic.dat", argc, argv);
UInt max_steps = 1000;
Real epot, ekin;
Mesh mesh(2);
mesh.read("square.msh");
mesh.createBoundaryGroupFromGeometry();
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step/10.);
model.assembleMassLumped();
std::cout << model << std::endl;
// Boundary condition (Neumann)
Matrix<Real> stress(2,2);
stress.eye(Real(1e3));
model.applyBC(BC::Neumann::FromHigherDim(stress), "boundary_0");
model.setBaseName ("square-orthotrope" );
model.addDumpFieldVector("displacement");
model.addDumpField ("mass" );
model.addDumpField ("velocity" );
model.addDumpField ("acceleration");
model.addDumpFieldVector("force" );
model.addDumpField ("residual" );
model.addDumpField ("stress" );
model.addDumpField ("grad_u" );
model.dump();
std::ofstream energy;
energy.open("energy.csv");
energy << "id,epot,ekin,tot" << std::endl;
for(UInt s = 0; s < max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
energy << s << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
if(s % 100 == 0) model.dump();
}
energy.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc
index 5f92c8265..074bcfb54 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc
@@ -1,96 +1,97 @@
/**
* @file test_material_thermal.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
- * @date creation: Thu Jan 16 2014
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the class akantu::MaterialThermal
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
debug::setDebugLevel(dblWarning);
initialize("material_thermal.dat", argc, argv);
Math::setTolerance(1.e-13);
Mesh mesh(2);
mesh.read("square.msh");
SolidMechanicsModel model(mesh);
model.initFull(SolidMechanicsModelOptions(_static));
mesh.computeBoundingBox();
const Vector<Real> & min = mesh.getLowerBounds();
const Vector<Real> & max = mesh.getUpperBounds();
Array<Real> & pos = mesh.getNodes();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & disp = model.getDisplacement();
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
if (Math::are_float_equal(pos(i, 0), min(0))) {
boundary(i, 0) = true;
}
if (Math::are_float_equal(pos(i, 1), min(1))) {
boundary(i, 1) = true;
}
}
model.setBaseName("test_material_thermal");
model.addDumpField("displacement");
model.addDumpField("strain");
model.addDumpField("stress");
model.addDumpField("delta_T");
model.solveStatic<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-10, 2);
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
if (Math::are_float_equal(pos(i, 0), max(0)) && Math::are_float_equal(pos(i, 1), max(1))) {
if (!Math::are_float_equal(disp(i, 0), 1.0) || !Math::are_float_equal(disp(i, 1), 1.0)) {
AKANTU_DEBUG_ERROR("Test not passed");
return EXIT_FAILURE;
}
}
}
model.dump();
finalize();
std::cout << "Test passed" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/CMakeLists.txt
index c826a0ffa..5781e0701 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/CMakeLists.txt
@@ -1,45 +1,47 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date Thu Aug 09 21:06:34 2012
+# @date creation: Thu Aug 09 2012
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for viscoelastic materials tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
add_mesh(test_material_standard_linear_solid_deviatoric_relaxation_mesh
test_material_standard_linear_solid_deviatoric_relaxation.geo 2 1)
register_test(test_material_standard_linear_solid_deviatoric_relaxation
SOURCES test_material_standard_linear_solid_deviatoric_relaxation.cc
DEPENDS test_material_standard_linear_solid_deviatoric_relaxation_mesh
FILES_TO_COPY material_standard_linear_solid_deviatoric_relaxation.dat
PACKAGE core
)
register_test(test_material_standard_linear_solid_deviatoric_relaxation_tension
SOURCES test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
DEPENDS test_material_standard_linear_solid_deviatoric_relaxation_mesh
FILES_TO_COPY material_standard_linear_solid_deviatoric_relaxation.dat
PACKAGE core
)
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.cc
index 87f690e2e..ba5989297 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.cc
@@ -1,165 +1,167 @@
/**
* @file test_material_standard_linear_solid_deviatoric_relaxation.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
*
- * @date Wed May 23 17:42:48 2012
+ * @date creation: Mon Aug 09 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the viscoelastic material: relaxation
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <sstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
using namespace akantu;
int main(int argc, char *argv[])
{
akantu::initialize("material_standard_linear_solid_deviatoric_relaxation.dat", argc, argv);
akantu::debug::setDebugLevel(akantu::dblWarning);
// sim data
Real T = 10.;
Real eps = 0.001;
const UInt dim = 2;
Real sim_time = 25.;
Real time_factor = 0.1;
Real tolerance = 1e-7;
Mesh mesh(dim);
mesh.read("test_material_standard_linear_solid_deviatoric_relaxation.msh");
const ElementType element_type = _quadrangle_4;
SolidMechanicsModel model(mesh);
/* ------------------------------------------------------------------------ */
/* Initialization */
/* ------------------------------------------------------------------------ */
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.assembleMassLumped();
std::stringstream filename_sstr;
filename_sstr << "test_material_standard_linear_solid_deviatoric_relaxation.out";
std::ofstream output_data;
output_data.open(filename_sstr.str().c_str());
output_data << "#[1]-time [2]-sigma_analytic [3+]-sigma_measurements" << std::endl;
Material & mat = model.getMaterial(0);
const Array<Real> & stress = mat.getStress(element_type);
Real Eta = mat.getParam<Real>("Eta");
Real EV = mat.getParam<Real>("Ev");
Real Einf = mat.getParam<Real>("Einf");
Real nu = mat.getParam<Real>("nu");
Real Ginf = Einf/(2*(1+nu));
Real G = EV/(2*(1+nu));
Real G0 = G + Ginf;
Real gamma = G/G0;
Real tau = Eta / EV;
Real gammainf = Ginf/G0;
UInt nb_nodes = mesh.getNbNodes();
const Array<Real> & coordinate = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
/// Setting time step
Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
UInt max_steps = sim_time / time_step;
UInt out_interval = 1;
Real time = 0.;
/* ------------------------------------------------------------------------ */
/* Main loop */
/* ------------------------------------------------------------------------ */
for(UInt s = 0; s <= max_steps; ++s) {
if(s % 1000 == 0)
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
time = s * time_step;
// impose displacement
Real epsilon = 0.;
if (time < T) {
epsilon = eps * time / T;
}
else {
epsilon = eps;
}
for (UInt n=0; n<nb_nodes; ++n) {
displacement(n,0) = epsilon * coordinate(n,1);
displacement(n,1) = epsilon * coordinate(n,0);
}
// compute stress
model.updateResidual();
// print output
if(s % out_interval == 0) {
// analytical solution
Real solution= 0.;
if (time < T) {
solution = 2 * G0 * eps / T * (gammainf * time + gamma * tau * (1 - exp(-time/tau)));
}
else {
solution = 2 * G0 * eps * (gammainf + gamma * tau / T * (exp((T-time)/tau) - exp(-time/tau)));
}
output_data << s*time_step << " " << solution;
// data output
Array<Real>::const_matrix_iterator stress_it = stress.begin(dim, dim);
Array<Real>::const_matrix_iterator stress_end = stress.end(dim, dim);
for(;stress_it != stress_end; ++stress_it) {
output_data << " " << (*stress_it)(0,1) << " " << (*stress_it)(1,0);
// test error
Real rel_error_1 = std::abs(((*stress_it)(0,1) - solution) / solution);
Real rel_error_2 = std::abs(((*stress_it)(1,0) - solution) / solution);
if (rel_error_1 > tolerance || rel_error_2 > tolerance) {
std::cerr << "Relative error: " << rel_error_1 << " " << rel_error_2 << std::endl;
return EXIT_FAILURE;
}
}
output_data << std::endl;
}
}
finalize();
std::cout << "Test successful!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation_tension.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
index 58dedfc77..ed705d5ef 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
@@ -1,172 +1,174 @@
/**
* @file test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date Wed May 30 17:16:16 2012
+ * @date creation: Mon Aug 09 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the viscoelastic material: relaxation
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <sstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
using namespace akantu;
int main(int argc, char *argv[])
{
akantu::initialize("material_standard_linear_solid_deviatoric_relaxation.dat", argc, argv);
// sim data
Real T = 10.;
Real eps = 0.001;
// const UInt dim = 3;
const UInt dim = 2;
Real sim_time = 25.;
//Real sim_time = 250.;
Real time_factor = 0.1;
Real tolerance = 1e-5;
Mesh mesh(dim);
mesh.read("test_material_standard_linear_solid_deviatoric_relaxation.msh");
// mesh_io.read("hexa_structured.msh",mesh);
//const ElementType element_type = _hexahedron_8;
const ElementType element_type = _quadrangle_4;
SolidMechanicsModel model(mesh);
/* ------------------------------------------------------------------------ */
/* Initialization */
/* ------------------------------------------------------------------------ */
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.assembleMassLumped();
model.updateResidual();
model.getMaterial(0).setToSteadyState();
std::stringstream filename_sstr;
filename_sstr << "test_material_standard_linear_solid_deviatoric_relaxation_tension.out";
std::ofstream output_data;
output_data.open(filename_sstr.str().c_str());
output_data << "#[1]-time [2]-sigma_analytic [3+]-sigma_measurements" << std::endl;
Material & mat = model.getMaterial(0);
const Array<Real> & stress = mat.getStress(element_type);
Real Eta = mat.getParam<Real>("Eta");
Real EV = mat.getParam<Real>("Ev");
Real Einf = mat.getParam<Real>("Einf");
Real E0 = mat.getParam<Real>("E");
Real kpa = mat.getParam<Real>("kapa");
Real mu = mat.getParam<Real>("mu");
Real gamma = EV/E0;
Real gammainf = Einf/E0;
Real tau = Eta / EV;
std::cout << "relaxation time = " << tau << std::endl;
UInt nb_nodes = mesh.getNbNodes();
const Array<Real> & coordinate = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
/// Setting time step
Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
UInt max_steps = sim_time / time_step;
UInt out_interval = 1;
Real time = 0.;
/* ------------------------------------------------------------------------ */
/* Main loop */
/* ------------------------------------------------------------------------ */
for(UInt s = 0; s <= max_steps; ++s) {
if(s % 1000 == 0)
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
time = s * time_step;
// impose displacement
Real epsilon = 0.;
if (time < T) {
epsilon = eps * time / T;
}
else {
epsilon = eps;
}
for (UInt n=0; n<nb_nodes; ++n) {
for (UInt d=0; d<dim; ++d)
displacement(n,d) = epsilon * coordinate(n,d);
}
// compute stress
model.updateResidual();
// print output
if(s % out_interval == 0) {
// analytical solution
Real epskk = dim * eps;
Real solution= 0.;
if (time < T) {
solution = 2 * mu * (eps - epskk/3.) / T * (gammainf * time + gamma * tau * (1 - exp(-time/tau))) + gammainf * kpa * epskk * time / T;
}
else {
solution = 2 * mu * (eps - epskk/3.) * (gammainf + gamma * tau / T *(exp((T-time)/tau) - exp(-time/tau))) + gammainf * kpa * epskk;
}
output_data << s*time_step << " " << solution;
// data output
Array<Real>::const_matrix_iterator stress_it = stress.begin(dim, dim);
Array<Real>::const_matrix_iterator stress_end = stress.end(dim, dim);
for(;stress_it != stress_end; ++stress_it) {
output_data << " " << (*stress_it)(1,1);
// test error
Real rel_error_1 = std::abs(((*stress_it)(1,1) - solution) / solution);
if (rel_error_1 > tolerance) {
std::cerr << "Relative error: " << rel_error_1 << std::endl;
return EXIT_FAILURE;
}
}
output_data << std::endl;
}
}
finalize();
std::cout << "Test successful!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d.cc
index be47ae8d2..d757f446d 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d.cc
@@ -1,197 +1,198 @@
/**
* @file test_solid_mechanics_model_bar_traction2d.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Sep 03 2010
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Mon Aug 09 2010
+ * @date last modification: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "solid_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
# include "io_helper.hh"
iohelper::ElemType paraview_type = iohelper::TRIANGLE2;
#endif //AKANTU_USE_IOHELPER
//#define CHECK_STRESS
akantu::ElementType type = akantu::_triangle_6;
akantu::SolidMechanicsModel * model;
akantu::UInt spatial_dimension = 2;
akantu::UInt nb_nodes;
akantu::UInt nb_element;
akantu::UInt nb_quadrature_points;
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
akantu::UInt max_steps = 5000;
akantu::Real time_factor = 0.8;
akantu::Mesh mesh(spatial_dimension);
mesh.read("bar2.msh");
akantu::SolidMechanicsModel model(mesh);
nb_nodes = mesh.getNbNodes();
nb_element = mesh.getNbElement(type);
/// model initialization
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.initMaterials();
model.assembleMassLumped();
mesh.createGroupsFromMeshData<std::string>("physical_names");
/// boundary conditions
akantu::Real eps = 1e-16;
const akantu::Array<akantu::Real> & pos = mesh.getNodes();
akantu::Array<akantu::Real> & disp = model.getDisplacement();
akantu::Array<bool> & boun = model.getBlockedDOFs();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
if(pos(i, 0) >= 9.) disp(i, 0) = (pos(i, 0) - 9) / 100.;
if(pos(i) <= eps) boun(i, 0) = true;
if(pos(i, 1) <= eps || pos(i, 1) >= 1 - eps ) boun(i, 1) = true;
}
/// set the time step
akantu::Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
/// initialize the paraview output
model.updateResidual();
mesh.setBaseName("bar_traction_2d");
model.addDumpField("displacement");
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpFieldTensor("stress");
model.addDumpField("grad_u" );
model.addDumpGroupField("displacement","Top");
model.dumpGroup("Top");
model.dump();
#ifdef CHECK_STRESS
std::ofstream outfile;
outfile.open("stress");
#endif // CHECK_STRESS
std::ofstream energy;
energy.open("energy_bar_2d.csv");
energy << "id,rtime,epot,ekin,tot" << std::endl;
for(akantu::UInt s = 1; s <= max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
akantu::Real epot = model.getEnergy("potential");
akantu::Real ekin = model.getEnergy("kinetic");
energy << s << "," << (s-1)*time_step << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
#ifdef CHECK_STRESS
/// search the position of the maximum of stress to determine the wave speed
akantu::Real max_stress = std::numeric_limits<akantu::Real>::min();
akantu::Real * stress = model.getMaterial(0).getStress(type).storage();
for (akantu::UInt i = 0; i < nb_element; ++i) {
if(max_stress < stress[i*spatial_dimension*spatial_dimension]) {
max_stress = stress[i*spatial_dimension*spatial_dimension];
}
}
akantu::Real * coord = model.getFEEngine().getMesh().getNodes().storage();
akantu::Real * disp_val = model.getDisplacement().storage();
akantu::UInt * conn = model.getFEEngine().getMesh().getConnectivity(type).storage();
akantu::UInt nb_nodes_per_element = model.getFEEngine().getMesh().getNbNodesPerElement(type);
akantu::Real * coords = new akantu::Real[spatial_dimension];
akantu::Real min_x = std::numeric_limits<akantu::Real>::max();
akantu::Real max_x = std::numeric_limits<akantu::Real>::min();
akantu::Real stress_range = 5e7;
for (akantu::UInt el = 0; el < nb_element; ++el) {
if(stress[el*spatial_dimension*spatial_dimension] > max_stress - stress_range) {
akantu::UInt el_offset = el * nb_nodes_per_element;
memset(coords, 0, spatial_dimension*sizeof(akantu::Real));
for (akantu::UInt n = 0; n < nb_nodes_per_element; ++n) {
for (akantu::UInt i = 0; i < spatial_dimension; ++i) {
akantu::UInt node = conn[el_offset + n] * spatial_dimension;
coords[i] += (coord[node + i] + disp_val[node + i])
/ ((akantu::Real) nb_nodes_per_element);
}
}
min_x = min_x < coords[0] ? min_x : coords[0];
max_x = max_x > coords[0] ? max_x : coords[0];
}
}
outfile << s << " " << .5 * (min_x + max_x) << " " << min_x << " " << max_x << " " << max_x - min_x << " " << max_stress << std::endl;
delete [] coords;
#endif // CHECK_STRESS
#ifdef AKANTU_USE_IOHELPER
if(s % 100 == 0) {
model.dump();
model.dumpGroup();
}
#endif //AKANTU_USE_IOHELPER
if(s % 100 == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
energy.close();
#ifdef CHECK_STRESS
outfile.close();
#endif // CHECK_STRESS
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_parallel.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_parallel.cc
index b2f6b18b8..ef7c761aa 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_parallel.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_parallel.cc
@@ -1,161 +1,163 @@
/**
* @file test_solid_mechanics_model_bar_traction2d_parallel.cc
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Sun Sep 12 2010
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 09 2010
+ * @date last modification: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include "mpi.h"
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
akantu::UInt spatial_dimension = 2;
akantu::UInt max_steps = 5000;
akantu::Real time_factor = 0.8;
akantu::initialize("material.dat", argc, argv);
akantu::Mesh mesh(spatial_dimension);
akantu::StaticCommunicator & comm =
akantu::StaticCommunicator::getStaticCommunicator();
akantu::Int psize = comm.getNbProc();
akantu::Int prank = comm.whoAmI();
akantu::debug::setDebugLevel(akantu::dblWarning);
akantu::MeshPartition * partition = NULL;
if(prank == 0) {
mesh.read("bar2.msh");
partition = new akantu::MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/* ------------------------------------------------------------------------ */
/* Initialization */
/* ------------------------------------------------------------------------ */
akantu::SolidMechanicsModel model(mesh);
/// model initialization
model.initParallel(partition);
model.initFull();
if(prank == 0)
std::cout << model.getMaterial(0) << std::endl;
model.assembleMassLumped();
akantu::UInt nb_nodes = mesh.getNbNodes();
/* ------------------------------------------------------------------------ */
/* Boundary + initial conditions */
/* ------------------------------------------------------------------------ */
akantu::Real eps = 1e-16;
const akantu::Array<akantu::Real> & pos = mesh.getNodes();
akantu::Array<akantu::Real> & disp = model.getDisplacement();
akantu::Array<bool> & boun = model.getBlockedDOFs();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
if(pos(i, 0) >= 9.) disp(i, 0) = (pos(i, 0) - 9) / 100.;
if(pos(i) <= eps) boun(i, 0) = true;
if(pos(i, 1) <= eps || pos(i, 1) >= 1 - eps ) boun(i, 1) = true;
}
model.synchronizeBoundaries();
model.updateResidual();
model.setBaseName("bar2d_parallel");
model.addDumpField("displacement");
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("stress" );
model.addDumpField("strain" );
model.addDumpField("partitions" );
model.dump();
std::ofstream energy;
if(prank == 0) {
energy.open("energy_bar_2d_para.csv");
energy << "id,rtime,epot,ekin,tot" << std::endl;
}
double total_time = 0.;
/// Setting time step
akantu::Real time_step = model.getStableTimeStep() * time_factor;
if(prank == 0)
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
/* ------------------------------------------------------------------------ */
/* Main loop */
/* ------------------------------------------------------------------------ */
for(akantu::UInt s = 1; s <= max_steps; ++s) {
double start = MPI_Wtime();
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
double end = MPI_Wtime();
akantu::Real epot = model.getEnergy("potential");
akantu::Real ekin = model.getEnergy("kinetic");
total_time += end - start;
if(prank == 0 && (s % 100 == 0)) {
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
}
energy << s << "," << (s-1)*time_step << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
if(s % 100 == 0) {
model.dump();
}
}
if(prank == 0) std::cout << "Time : " << psize << " " << total_time / max_steps << " " << total_time << std::endl;
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_structured.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_structured.cc
index a93decdbd..659b29ceb 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_structured.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_structured.cc
@@ -1,100 +1,101 @@
/**
* @file test_solid_mechanics_model_bar_traction2d_structured.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
int main(int argc, char *argv[]) {
akantu::initialize("material.dat", argc, argv);
akantu::UInt spatial_dimension = 2;
akantu::UInt max_steps = 10000;
akantu::Real time_factor = 0.2;
akantu::Real epot, ekin;
akantu::Mesh mesh(spatial_dimension);
mesh.read("bar_structured1.msh");
akantu::SolidMechanicsModel * model = new akantu::SolidMechanicsModel(mesh);
/// model initialization
model->initFull();
std::cout << model->getMaterial(0) << std::endl;
/// boundary conditions
akantu::Real eps = 1e-16;
for (akantu::UInt i = 0; i < mesh.getNbNodes(); ++i) {
if(mesh.getNodes()(i) >= 9)
model->getDisplacement()(i) = (model->getFEEngine().getMesh().getNodes()(i) - 9) / 100. ;
if(mesh.getNodes()(i) <= eps)
model->getBlockedDOFs()(i) = true;
if(mesh.getNodes()(i, 1) <= eps ||
mesh.getNodes()(i, 1) >= 1 - eps ) {
model->getBlockedDOFs()(i, 1) = true;
}
}
akantu::Real time_step = model->getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model->setTimeStep(time_step);
std::ofstream energy;
energy.open("energy_bar_2d_structured.csv");
energy << "id,epot,ekin,tot" << std::endl;
for(akantu::UInt s = 1; s <= max_steps; ++s) {
model->explicitPred();
model->updateResidual();
model->updateAcceleration();
model->explicitCorr();
epot = model->getEnergy("potential");
ekin = model->getEnergy("kinetic");
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
energy << s << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
}
energy.close();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_structured_pbc.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_structured_pbc.cc
index c83ad0bdc..130b7f582 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_structured_pbc.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_structured_pbc.cc
@@ -1,126 +1,128 @@
/**
* @file test_solid_mechanics_model_bar_traction2d_structured_pbc.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Dec 22 2011
- * @date last modification: Mon Jun 23 2014
+ * @date last modification: Thu Aug 06 2015
*
* @brief test of pbc class for SolidMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
akantu::debug::setDebugLevel(akantu::dblWarning);
akantu::initialize("material.dat", argc, argv);
akantu::UInt spatial_dimension = 2;
akantu::UInt max_steps = 1000;
akantu::Real time_factor = 0.2;
akantu::Real epot, ekin;
akantu::Mesh mesh(spatial_dimension);
mesh.read("bar_structured1.msh");
akantu::SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.setPBC(1,0,0);
model.initPBC();
model.assembleMassLumped();
model.setBaseName("bar2d_structured_pbc");
model.addDumpField("displacement");
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("stress" );
model.addDumpField("strain" );
model.dump();
akantu::UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
mesh.computeBoundingBox();
akantu::Real eps = 1e-16;
akantu::Real signal_start = 0.6*mesh.getUpperBounds()(0);
akantu::Real signal_end = 0.7*mesh.getUpperBounds()(0);
akantu::Real delta_d = signal_end - signal_start;
akantu::Real signal = 1.;
const akantu::Array<akantu::Real> & coords = model.getFEEngine().getMesh().getNodes();
akantu::Array<akantu::Real> & disp = model.getDisplacement();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
if(coords(i,0) >= signal_start && coords(i,0) <= signal_end) {
if (coords(i,0) <= 0.5 * (signal_start + signal_end))
disp(i,0) = (coords(i,0) - signal_start) * 2 * signal / delta_d;
else
disp(i,0) = (signal_end - coords(i,0)) * 2 * signal / delta_d;
}
if(coords(i,1) <= eps || coords(i,1) >= 1 - eps ) {
model.getBlockedDOFs().storage()[spatial_dimension*i + 1] = true;
}
}
akantu::Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
std::ofstream energy;
energy.open("energy_2d_pbc.csv");
energy << "id,epot,ekin,tot" << std::endl;
for(akantu::UInt s = 1; s <= max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
if(s % 20 == 0) model.dump();
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
energy << s << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
}
energy.close();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_boundary_condition.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_boundary_condition.cc
index a411f17d2..59d548558 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_boundary_condition.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_boundary_condition.cc
@@ -1,89 +1,89 @@
/**
* @file test_solid_mechanics_model_boundary_condition.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
*
* @date creation: Fri May 03 2013
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test of the boundary condition class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <iostream>
#include <sstream>
#include "aka_common.hh"
#include "aka_error.hh"
#include "mesh.hh"
#include "solid_mechanics_model.hh"
#include "boundary_condition_functor.hh"
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char* argv[])
{
UInt spatial_dimension(3);
akantu::initialize("material.dat", argc, argv);
Mesh mesh(spatial_dimension, "mesh_names");
std::cout << "Loading the mesh." << std::endl;
mesh.read("./cube_physical_names.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
std::stringstream sstr;
SolidMechanicsModel model(mesh);
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
Vector<Real> surface_traction(3);
surface_traction(0)=0.0;
surface_traction(1)=0.0;
surface_traction(2)=-1.0;
Matrix<Real> surface_stress(3, 3, 0.0);
surface_stress(0,0)=0.0;
surface_stress(1,1)=0.0;
surface_stress(2,2)=-1.0;
model.applyBC(BC::Dirichlet::FixedValue(13.0, _x), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(13.0, _y), "Bottom");
model.applyBC(BC::Dirichlet::FixedValue(13.0, _z), "Bottom");
//model.applyBC(BC::Neumann::FromSameDim(surface_traction), "Top");
model.applyBC(BC::Neumann::FromHigherDim(surface_stress), "Top");
debug::setDebugLevel(dblTest);
std::cout << model.getDisplacement();
std::cout << model.getForce();
debug::setDebugLevel(dblInfo);
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_circle_2.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_circle_2.cc
index 118a15ff4..432ab26e7 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_circle_2.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_circle_2.cc
@@ -1,98 +1,99 @@
/**
* @file test_solid_mechanics_model_circle_2.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Oct 26 2010
- * @date last modification: Thu Apr 03 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Tue Aug 04 2015
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
UInt max_steps = 10000;
Real epot, ekin, wext = 0;
Mesh mesh(2);
mesh.read("circle2.msh");
mesh.createBoundaryGroupFromGeometry();
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
Real time_step = model.getStableTimeStep() / 10.;
model.setTimeStep(time_step);
std::cout << "-- Time step : " << time_step << " --" << std::endl;
model.assembleMassLumped();
// Boundary condition (Neumann)
Matrix<Real> stress(2,2);
stress.eye(Real(1e3));
model.applyBC(BC::Neumann::FromHigherDim(stress), "boundary_0");
model.setBaseName("circle2");
model.addDumpFieldVector("displacement");
model.addDumpFieldVector("force" );
model.addDumpFieldVector("residual" );
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("stress" );
model.addDumpField("strain" );
model.dump();
for(UInt s = 0; s < max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
wext += model.getEnergy("external work");
std::cout << s << "," << epot << "," << ekin << "," << wext << "," << epot + ekin - wext
<< std::endl;
if(s % 100 == 0) model.dump();
}
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d.cc
index 9d174da36..d158f8e60 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d.cc
@@ -1,111 +1,112 @@
/**
* @file test_solid_mechanics_model_cube3d.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
- * @date creation: Fri Sep 03 2010
- * @date last modification: Wed Sep 17 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
akantu::UInt max_steps = 10000;
akantu::Real epot, ekin;
akantu::Mesh mesh(3);
mesh.read("cube1.msh");
akantu::SolidMechanicsModel model(mesh);
model.initFull();
akantu::Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step/10.);
model.assembleMassLumped();
std::cout << model << std::endl;
/// boundary conditions
akantu::UInt nb_nodes = mesh.getNbNodes();
akantu::Real eps = 1e-16;
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
model.getDisplacement().storage()[3*i] = model.getFEEngine().getMesh().getNodes().storage()[3*i] / 100.;
if(model.getFEEngine().getMesh().getNodes().storage()[3*i] <= eps) {
model.getBlockedDOFs().storage()[3*i ] = true;
}
if(model.getFEEngine().getMesh().getNodes().storage()[3*i + 1] <= eps) {
model.getBlockedDOFs().storage()[3*i + 1] = true;
}
}
model.setBaseName("cube3d");
model.addDumpField("displacement");
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("stress" );
model.addDumpField("grad_u" );
model.addDumpField("element_index_by_material");
model.dump();
std::ofstream energy;
energy.open("energy.csv");
energy << "id,epot,ekin,tot" << std::endl;
for(akantu::UInt s = 0; s < max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
energy << s << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
if(s % 10 == 0) model.dump();
}
energy.close();
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d_pbc.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d_pbc.cc
index 51bb61113..b0eea7766 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d_pbc.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d_pbc.cc
@@ -1,111 +1,112 @@
/**
* @file test_solid_mechanics_model_cube3d_pbc.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
- * @date creation: Fri May 18 2012
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
akantu::UInt max_steps = 10000;
akantu::Real epot, ekin;
akantu::Mesh mesh(3);
mesh.read("cube_structured.msh");
akantu::SolidMechanicsModel model(mesh);
model.setPBC(1,1,1);
model.initFull();
akantu::Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step/10.);
model.assembleMassLumped();
std::cout << model << std::endl;
/// boundary conditions
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
akantu::Real eps = 1e-16;
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
model.getDisplacement().storage()[3*i] = model.getFEEngine().getMesh().getNodes().storage()[3*i] / 100.;
if(model.getFEEngine().getMesh().getNodes().storage()[3*i] <= eps) {
model.getBlockedDOFs().storage()[3*i ] = true;
}
if(model.getFEEngine().getMesh().getNodes().storage()[3*i + 1] <= eps) {
model.getBlockedDOFs().storage()[3*i + 1] = true;
}
}
model.setBaseName("cube3d_pbc");
model.addDumpField("displacement");
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("stress" );
model.addDumpField("strain" );
model.dump();
std::ofstream energy;
energy.open("energy.csv");
energy << "id,epot,ekin,tot" << std::endl;
for(akantu::UInt s = 0; s < max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
energy << s << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
if(s % 10 == 0) model.dump();
}
energy.close();
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d_tetra10.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d_tetra10.cc
index b94addff5..7c938d3fe 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d_tetra10.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_cube3d_tetra10.cc
@@ -1,113 +1,114 @@
/**
* @file test_solid_mechanics_model_cube3d_tetra10.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Peter Spijker <peter.spijker@epfl.ch>
*
- * @date creation: Mon Dec 06 2010
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel on the 3d cube
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
akantu::initialize("material.dat", argc, argv);
akantu::UInt max_steps = 1000;
akantu::Real epot, ekin;
akantu::Mesh mesh(3);
mesh.read("cube2.msh");
akantu::SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
akantu::Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step/10.);
model.assembleMassLumped();
std::cout << model << std::endl;
/// boundary conditions
akantu::Real eps = 1e-2;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
model.getDisplacement().storage()[3*i] = model.getFEEngine().getMesh().getNodes().storage()[3*i] / 100.;
if(model.getFEEngine().getMesh().getNodes().storage()[3*i] <= eps) {
model.getBlockedDOFs().storage()[3*i ] = true;
}
if(model.getFEEngine().getMesh().getNodes().storage()[3*i + 1] <= eps) {
model.getBlockedDOFs().storage()[3*i + 1] = true;
}
}
// model.getDisplacement().storage()[1] = 0.1;
model.setBaseName("cube3d_t10");
model.addDumpField("displacement");
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("stress" );
model.addDumpField("strain" );
model.dump();
std::ofstream energy;
energy.open("energy.csv");
energy << "id,epot,ekin,tot" << std::endl;
for(akantu::UInt s = 0; s < max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
energy << s << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
if(s % 10 == 0) model.dump();
}
energy.close();
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_1d.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_1d.cc
index 7c4509e7c..60a4d4b61 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_1d.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_1d.cc
@@ -1,80 +1,81 @@
/**
* @file test_solid_mechanics_model_implicit_1d.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Mar 03 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 09 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of traction in implicit
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[])
{
initialize("material.dat", argc, argv);
UInt spatial_dimension = 1;
Mesh mesh(spatial_dimension);
mesh.read("segment1.msh");
SolidMechanicsModel model(mesh);
model.initFull( SolidMechanicsModelOptions(_static));
std::cout << model.getMaterial(0) << std::endl;
/// boundary conditions
model.getBlockedDOFs()(0,0) = true;
model.getForce()(1,0) = 1000;
model.setBaseName("implicit_1d");
model.addDumpField("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("stress" );
model.addDumpField("strain" );
debug::setDebugLevel(dblInfo);
model.dump();
model.solveStep<_scm_newton_raphson_tangent_modified, _scc_residual>(1e-1, 10);
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_2d.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_2d.cc
index 65127ae67..1cc373f2d 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_2d.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_2d.cc
@@ -1,110 +1,111 @@
/**
* @file test_solid_mechanics_model_implicit_2d.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Mar 03 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 09 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of traction in implicit
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#define bar_length 1
#define bar_height 1
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
debug::setDebugLevel(dblWarning);
initialize("material.dat", argc, argv);
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
MeshPartition * partition = NULL;
if(prank == 0) {
mesh.read("square_implicit2.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
// partition->reorder();
partition->partitionate(psize);
}
SolidMechanicsModel model(mesh);
/// model initialization
model.initParallel(partition);
delete partition;
model.initFull(SolidMechanicsModelOptions(_static));
if (prank == 0) std::cout << model.getMaterial("steel") << std::endl;
/// boundary conditions
const Array<Real> & position = mesh.getNodes();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacment = model.getDisplacement();
UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (UInt n = 0; n < nb_nodes; ++n) {
if(position(n,0) < Math::getTolerance()) boundary(n,0) = true;
if(position(n,1) < Math::getTolerance()) boundary(n,1) = true;
if(std::abs(position(n,0) - bar_length) < Math::getTolerance()) {
boundary(n,0) = true;
displacment(n,0) = 0.1;
}
}
model.setBaseName("implicit_2d");
model.addDumpField("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("stress" );
model.addDumpField("strain" );
model.updateResidual();
model.dump();
model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-3, 100);
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_dynamic_2d.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_dynamic_2d.cc
index 7f65ee441..cfa92b62b 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_dynamic_2d.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_implicit_dynamic_2d.cc
@@ -1,211 +1,212 @@
/**
* @file test_solid_mechanics_model_implicit_dynamic_2d.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed May 11 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief test of the dynamic implicit code
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
using namespace akantu;
/* -------------------------------------------------------------------------- */
#define bar_length 10.
#define bar_height 1.
#define bar_depth 1.
const ElementType TYPE = _triangle_6;
//const ElementType TYPE = _tetrahedron_10;
const UInt spatial_dimension = 2;
Real time_step = 1e-4;
const Real F = 0.5e4;
const Real L = bar_length;
const Real I = bar_depth * bar_height * bar_height * bar_height / 12.;
const Real E = 12e7;
const Real rho = 1000;
const Real m = rho * bar_height * bar_depth;
static Real w(UInt n) {
return n*n*M_PI*M_PI/(L*L)*sqrt(E*I/m);
}
static Real analytical_solution(Real time) {
return 2*F*L*L*L/(pow(M_PI, 4)*E*I) * ((1. - cos(w(1)*time)) + (1. - cos(w(3)*time))/81. + (1. - cos(w(5)*time))/625.);
}
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
debug::setDebugLevel(dblError);
initialize("material_implicit_dynamic.dat", argc, argv);
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
MeshPartition * partition = NULL;
if(prank == 0) {
mesh.read("beam_2d_quad.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
SolidMechanicsModel model(mesh);
model.initParallel(partition);
/// model initialization
model.initFull(SolidMechanicsModelOptions(_implicit_dynamic));
Material &mat = model.getMaterial(0);
mat.setParam("E", E);
mat.setParam("rho", rho);
// boundary conditions
const Array<Real> & position = mesh.getNodes();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & force = model.getForce();
Array<Real> & displacment = model.getDisplacement();
//initial conditions
UInt node_to_print = UInt(-1);
bool print_node = false;
Array<UInt> node_to_displace;
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
Real x = position(n, 0);
Real y = position(n, 1);
Real z = 0;
if(spatial_dimension == 3)
z = position(n, 2);
if(Math::are_float_equal(x, 0.) &&
Math::are_float_equal(y, bar_height / 2.)) {
boundary(n,0) = true;
boundary(n,1) = true;
if(spatial_dimension == 3 && Math::are_float_equal(z, bar_depth / 2.))
boundary(n,2) = true;
}
if(Math::are_float_equal(x, bar_length) &&
Math::are_float_equal(y, bar_height / 2.)) {
boundary(n,1) = true;
if(spatial_dimension == 3 && Math::are_float_equal(z, bar_depth / 2.))
boundary(n,2) = true;
}
if(Math::are_float_equal(x, bar_length / 2.) &&
Math::are_float_equal(y, bar_height / 2.)) {
if(spatial_dimension < 3 || (spatial_dimension == 3 && Math::are_float_equal(z, bar_depth / 2.))) {
force(n,1) = F;
if(mesh.isLocalOrMasterNode(n)) {
print_node = true;
node_to_print = n;
std::cout << "I, proc " << prank +1 << " handle the print of node " << n
<< "(" << x << ", "<< y << ", " << z << ")" << std::endl;
}
}
}
}
model.setTimeStep(time_step);
model.updateResidual();
std::stringstream out;
out << "position-" << TYPE << "_" << std::scientific << time_step << ".csv";
model.setBaseName("implicit_dynamic");
model.addDumpField("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("stress" );
model.addDumpField("strain" );
std::ofstream pos;
if(print_node) {
pos.open(out.str().c_str());
if(!pos.good()) {
std::cerr << "Cannot open file " << out.str() <<std::endl;
exit(EXIT_FAILURE);
}
pos << "id,time,position,solution" << std::endl;
}
Real time = 0;
// UInt count = 0;
// Real error;
model.assembleStiffnessMatrix();
//model.assembleMass();
/// time loop
for (UInt s = 1; time < 0.0062; ++s) {
model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-12, 1000);
// model.implicitPred();
// /// convergence loop
// do {
// if(count > 0 && prank == 0)
// std::cout << "passing step " << s << " " << s * time_step << "s - " << std::setw(4) << count << " : " << std::scientific << error << "\r" << std::flush;
// model.updateResidual();
// model.solveDynamic();
// model.implicitCorr();
// count++;
// } while(!model.testConvergenceIncrement(1e-12, error) && (count < 1000));
// count = 0;
if(prank == 0) std::cout << "passing step " << s << " " << s * time_step << "s\r" << std::flush;
if(print_node) pos << s << "," << s * time_step << "," << displacment(node_to_print, 1) << "," << analytical_solution(s*time_step) << std::endl;
if(s % 10 == 0) {
model.computeStresses ();
}
time += time_step;
}
if(print_node) pos.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
index 09baf71cf..1cde66b46 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
@@ -1,209 +1,210 @@
/**
* @file test_solid_mechanics_model_material_eigenstrain.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Mon Feb 10 2014
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Sat Apr 16 2011
+ * @date last modification: Wed Aug 12 2015
*
* @brief test the internal field prestrain
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "solid_mechanics_model.hh"
using namespace akantu;
Real alpha [3][4] = { { 0.01, 0.02, 0.03, 0.04 },
{ 0.05, 0.06, 0.07, 0.08 },
{ 0.09, 0.10, 0.11, 0.12 } };
/* -------------------------------------------------------------------------- */
template<ElementType type, bool is_plane_strain>
static Matrix<Real> prescribed_strain() {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> strain(spatial_dimension, spatial_dimension);
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
strain(i, j) = alpha[i][j + 1];
}
}
return strain;
}
template<ElementType type, bool is_plane_strain>
static Matrix<Real> prescribed_stress(Matrix<Real> prescribed_eigengradu) {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> stress(spatial_dimension, spatial_dimension);
//plane strain in 2d
Matrix<Real> strain(spatial_dimension, spatial_dimension);
Matrix<Real> pstrain;
pstrain = prescribed_strain<type, is_plane_strain>();
Real nu = 0.3;
Real E = 2.1e11;
Real trace = 0;
/// symetric part of the strain tensor
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
strain(i,j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
// elastic strain is equal to elastic strain minus the eigenstrain
strain -= prescribed_eigengradu;
for (UInt i = 0; i < spatial_dimension; ++i) trace += strain(i,i);
Real lambda = nu * E / ((1 + nu) * (1 - 2*nu));
Real mu = E / (2 * (1 + nu));
if(!is_plane_strain) {
std::cout << "toto" << std::endl;
lambda = nu * E / (1 - nu*nu);
}
if(spatial_dimension == 1) {
stress(0, 0) = E * strain(0, 0);
} else {
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j) {
stress(i, j) = (i == j)*lambda*trace + 2*mu*strain(i, j);
}
}
return stress;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
initialize("material_elastic_plane_strain.dat", argc, argv);
UInt dim = 3;
const ElementType element_type = _tetrahedron_4;
const bool plane_strain = true;
Matrix<Real> prescribed_eigengradu(dim, dim);
prescribed_eigengradu.clear();
for (UInt i = 0; i < dim; ++i) {
for (UInt j = 0; j < dim; ++j)
prescribed_eigengradu(i,j) += 0.1;
}
/// load mesh
Mesh my_mesh(dim);
std::stringstream filename; filename << "cube_3d_tet_4.msh";
my_mesh.read(filename.str());
/// declaration of model
SolidMechanicsModel my_model(my_mesh);
/// model initialization
my_model.initFull(SolidMechanicsModelOptions(_static));
const Array<Real> & coordinates = my_mesh.getNodes();
Array<Real> & displacement = my_model.getDisplacement();
Array<bool> & boundary = my_model.getBlockedDOFs();
MeshUtils::buildFacets(my_mesh);
my_mesh.createBoundaryGroupFromGeometry();
// Loop over (Sub)Boundar(ies)
for(GroupManager::const_element_group_iterator it(my_mesh.element_group_begin());
it != my_mesh.element_group_end(); ++it) {
for(ElementGroup::const_node_iterator nodes_it(it->second->node_begin());
nodes_it!= it->second->node_end(); ++nodes_it) {
UInt n(*nodes_it);
std::cout << "Node " << *nodes_it << std::endl;
for (UInt i = 0; i < dim; ++i) {
displacement(n, i) = alpha[i][0];
for (UInt j = 0; j < dim; ++j) {
displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
}
boundary(n, i) = true;
}
}
}
/* ------------------------------------------------------------------------ */
/* Apply eigenstrain in each element */
/* ------------------------------------------------------------------------ */
Array<Real> & eigengradu_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getInternal<Real>("eigen_grad_u")(element_type));
Array<Real>::iterator< Matrix<Real> > eigengradu_it = eigengradu_vect.begin(dim, dim);
Array<Real>::iterator< Matrix<Real> > eigengradu_end = eigengradu_vect.end(dim, dim);
for (; eigengradu_it != eigengradu_end; ++eigengradu_it) {
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
(*eigengradu_it)(i,j) += prescribed_eigengradu(i,j);
}
/* ------------------------------------------------------------------------ */
/* Static solve */
/* ------------------------------------------------------------------------ */
my_model.solveStep<_scm_newton_raphson_tangent_modified, _scc_residual>(2e-4, 2);
/* ------------------------------------------------------------------------ */
/* Checks */
/* ------------------------------------------------------------------------ */
Array<Real> & stress_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getStress(element_type));
Array<Real>::iterator< Matrix<Real> > stress_it = stress_vect.begin(dim, dim);
Array<Real>::iterator< Matrix<Real> > stress_end = stress_vect.end(dim, dim);
Matrix<Real> presc_stress;
presc_stress = prescribed_stress<element_type, plane_strain>(prescribed_eigengradu);
Real stress_tolerance = 1e-13;
for (; stress_it != stress_end; ++stress_it) {
Matrix<Real> & stress = *stress_it;
Matrix<Real> diff(dim, dim);
diff = stress;
diff -= presc_stress;
Real stress_error = diff.norm<L_inf>() / stress.norm<L_inf>();
if(stress_error > stress_tolerance) {
std::cerr << "stress error: " << stress_error << " > " << stress_tolerance << std::endl;
std::cerr << "stress: " << stress << std::endl
<< "prescribed stress: " << presc_stress << std::endl;
return EXIT_FAILURE;
} else {
std::cerr << "stress error: " << stress_error << " < " << stress_tolerance << std::endl;
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc
index 02480414b..29b30e5b7 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc
@@ -1,217 +1,217 @@
/**
* @file test_solid_mechanics_model_reassign_material.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Mon Feb 10 2014
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Wed Feb 25 2015
*
* @brief test the function reassign material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "static_communicator.hh"
#include "solid_mechanics_model.hh"
#include "material.hh"
#include "aka_grid_dynamic.hh"
using namespace akantu;
class StraightInterfaceMaterialSelector : public MaterialSelector {
public:
StraightInterfaceMaterialSelector(SolidMechanicsModel & model,
const std::string & mat_1_material,
const std::string & mat_2_material,
bool & horizontal,
Real & pos_interface) :
model(model),
mat_1_material(mat_1_material),
mat_2_material(mat_2_material),
horizontal(horizontal),
pos_interface(pos_interface) {
Mesh & mesh = model.getMesh();
UInt spatial_dimension = mesh.getSpatialDimension();
/// store barycenters of all elements
mesh.initElementTypeMapArray(barycenters, spatial_dimension, spatial_dimension);
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Element e;
e.ghost_type = ghost_type;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
e.type = *it;
Array<Real> & barycenter = barycenters(*it, ghost_type);
barycenter.resize(nb_element);
Array<Real>::iterator< Vector<Real> > bary_it = barycenter.begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem) {
e.element = elem;
mesh.getBarycenter(e, *bary_it);
++bary_it;
}
}
}
}
UInt operator()(const Element & elem) {
UInt spatial_dimension = model.getSpatialDimension();
const Vector<Real> & bary = barycenters(elem.type, elem.ghost_type).begin(spatial_dimension)[elem.element];
/// check for a given element on which side of the material interface plane the bary center lies and assign corresponding material
if (bary(!horizontal) < pos_interface) {
return model.getMaterialIndex(mat_1_material);;
}
return model.getMaterialIndex(mat_2_material);;
}
bool isConditonVerified() {
/// check if material has been (re)-assigned correctly
Mesh & mesh = model.getMesh();
UInt spatial_dimension = mesh.getSpatialDimension();
GhostType ghost_type = _not_ghost;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
Array<UInt> & mat_indexes = model.getMaterialByElement(*it, ghost_type);
UInt nb_element = mesh.getNbElement(*it, ghost_type);
Array<Real>::iterator<Vector<Real> > bary = barycenters(*it, ghost_type).begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem, ++bary) {
/// compare element_index_by material to material index that should be assigned due to the geometry of the interface
UInt mat_index;
if ((*bary)(!horizontal) < pos_interface)
mat_index = model.getMaterialIndex(mat_1_material);
else
mat_index = model.getMaterialIndex(mat_2_material);
if (mat_indexes(elem) != mat_index)
/// wrong material index, make test fail
return false;
}
}
return true;
}
void moveInterface(Real & pos_new, bool & horizontal_new) {
/// update position and orientation of material interface plane
pos_interface = pos_new;
horizontal = horizontal_new;
model.reassignMaterial();
}
protected:
SolidMechanicsModel & model;
ElementTypeMapArray<Real> barycenters;
std::string mat_1_material;
std::string mat_2_material;
bool horizontal;
Real pos_interface;
};
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
bool test_passed;
debug::setDebugLevel(dblWarning);
initialize("two_materials.dat", argc, argv);
/// specify position and orientation of material interface plane
bool horizontal = true;
Real pos_interface = 0.;
UInt spatial_dimension = 3;
akantu::StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
akantu::Int psize = comm.getNbProc();
akantu::Int prank = comm.whoAmI();
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
if(prank == 0) {
/// creation mesh
mesh.read("cube_two_materials.msh");
partition = new akantu::MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModel model(mesh);
model.initParallel(partition);
delete partition;
/// assign the two different materials using the StraightInterfaceMaterialSelector
StraightInterfaceMaterialSelector * mat_selector;
mat_selector = new StraightInterfaceMaterialSelector(model, "mat_1", "mat_2", horizontal, pos_interface);
model.setMaterialSelector(*mat_selector);
model.initFull(SolidMechanicsModelOptions(_static));
MeshUtils::buildFacets(mesh);
// model.setBaseName("test_reassign_material");
// model.addDumpField("element_index_by_material");
// model.addDumpField("partitions");
// model.dump();
/// check if different materials have been assigned correctly
test_passed = mat_selector->isConditonVerified();
if (!test_passed) {
AKANTU_DEBUG_ERROR("materials not correctly assigned");
return EXIT_FAILURE;
}
/// change orientation of material interface plane
horizontal = false;
mat_selector->moveInterface(pos_interface, horizontal);
// model.dump();
/// test if material has been reassigned correctly
test_passed = mat_selector->isConditonVerified();
if (!test_passed) {
AKANTU_DEBUG_ERROR("materials not correctly reassigned");
return EXIT_FAILURE;
}
finalize();
if(prank == 0)
std::cout << "OK: test passed!" << std::endl;
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_segment_parallel.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_segment_parallel.cc
index 72afecf70..cad027aac 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_segment_parallel.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_segment_parallel.cc
@@ -1,116 +1,117 @@
/**
* @file test_solid_mechanics_model_segment_parallel.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Sun Sep 26 2010
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Mon Aug 09 2010
+ * @date last modification: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
akantu::UInt spatial_dimension = 1;
akantu::UInt max_steps = 10000;
akantu::Real time_factor = 0.2;
akantu::initialize("material.dat", argc, argv);
akantu::Mesh mesh(spatial_dimension);
akantu::StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
akantu::Int psize = comm.getNbProc();
akantu::Int prank = comm.whoAmI();
akantu::debug::setDebugLevel(akantu::dblInfo);
akantu::MeshPartition * partition = NULL;
if(prank == 0) {
mesh.read("segment.msh");
partition = new akantu::MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
akantu::SolidMechanicsModel model(mesh);
model.initParallel(partition);
/// model initialization
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.assembleMassLumped();
model.setBaseName("segment_parallel");
model.addDumpField("displacement");
model.addDumpField("mass" );
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("stress" );
model.addDumpField("strain" );
/// boundary conditions
for (akantu::UInt i = 0; i < mesh.getNbNodes(); ++i) {
model.getDisplacement().storage()[spatial_dimension*i] = model.getFEEngine().getMesh().getNodes().storage()[i] / 100. ;
if(model.getFEEngine().getMesh().getNodes().storage()[spatial_dimension*i] <= 1e-15)
model.getBlockedDOFs().storage()[i] = true;
}
akantu::Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
for(akantu::UInt s = 1; s <= max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
akantu::Real epot = model.getEnergy("potential");
akantu::Real ekin = model.getEnergy("kinetic");
if(prank == 0) {
std::cout << s << " " << epot << " " << ekin << " " << epot + ekin
<< std::endl;
}
model.dump();
if(s % 10 == 0) std::cerr << "passing step " << s << "/" << max_steps << std::endl;
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_square.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_square.cc
index d2c5050a2..2471197c3 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_square.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_square.cc
@@ -1,102 +1,103 @@
/**
* @file test_solid_mechanics_model_square.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Sep 22 2010
- * @date last modification: Fri Apr 04 2014
+ * @date creation: Wed Aug 04 2010
+ * @date last modification: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
akantu::initialize("material.dat", argc, argv);
UInt max_steps = 1000;
Real epot, ekin;
Mesh mesh(2);
mesh.read("square.msh");
mesh.createBoundaryGroupFromGeometry();
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step/10.);
model.assembleMassLumped();
std::cout << model << std::endl;
// Boundary condition (Neumann)
Matrix<Real> stress(2,2);
stress.eye(Real(1e3));
model.applyBC(BC::Neumann::FromHigherDim(stress), "boundary_0");
model.setBaseName ("square" );
model.addDumpFieldVector("displacement");
model.addDumpField ("mass" );
model.addDumpField ("velocity" );
model.addDumpField ("acceleration");
model.addDumpFieldVector("force" );
model.addDumpField ("residual" );
model.addDumpField ("stress" );
model.addDumpField ("strain" );
model.dump();
std::ofstream energy;
energy.open("energy.csv");
energy << "id,epot,ekin,tot" << std::endl;
for(UInt s = 0; s < max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
energy << s << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
if(s % 100 == 0) model.dump();
}
energy.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_structural_mechanics_model/CMakeLists.txt b/test/test_model/test_structural_mechanics_model/CMakeLists.txt
index efcd140bd..e2214394b 100644
--- a/test/test_model/test_structural_mechanics_model/CMakeLists.txt
+++ b/test/test_model/test_structural_mechanics_model/CMakeLists.txt
@@ -1,72 +1,73 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Fabian Barras <fabian.barras@epfl.ch>
#
-# @date creation: Fri Jul 15 2011
-# @date last modification: Mon Jul 07 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief Structural Mechanics Model Tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
register_test(test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1
test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1.cc
PACKAGE structural_mechanics
)
register_test(test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1_y
test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1_y.cc
PACKAGE structural_mechanics
)
register_test(test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_xy
test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_xy.cc
PACKAGE structural_mechanics
)
register_test(test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_zy
test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_zy.cc
PACKAGE structural_mechanics
)
register_test(test_structural_mechanics_model_bernoulli_beam_3_exercice_12_10_13
test_structural_mechanics_model_bernoulli_beam_3_exercice_12_10_13.cc
PACKAGE structural_mechanics
)
register_test(test_structural_mechanics_model_bernoulli_beam_dynamics
test_structural_mechanics_model_bernoulli_beam_dynamics.cc
PACKAGE structural_mechanics
)
register_test(test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5
test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc
PACKAGE structural_mechanics
)
add_mesh(complicated_mesh complicated.geo 1 1)
register_test(test_structural_mechanics_model_bernoulli_beam_2_complicated
test_structural_mechanics_model_bernoulli_beam_2_complicated.cc
DEPENDS complicated_mesh
PACKAGE structural_mechanics
)
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_12_10_13.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_12_10_13.cc
index 39ab9d611..fa3fe39eb 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_12_10_13.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_12_10_13.cc
@@ -1,28 +1,32 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_12_10_13.cc
+ *
* @author Fabian Barras <fabian.barras@epfl.ch>
- * @date Tue Nov 29 09:16:11 2011
*
- * @brief
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Sun Oct 19 2014
+ *
+ * @brief Test for structural elements beam3d
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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/>.
*
*/
/* -------------------------------------------------------------------------- */
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_complicated.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_complicated.cc
index 607ecb034..70e871aeb 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_complicated.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_complicated.cc
@@ -1,164 +1,165 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_2_complicated.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Fri Jul 15 2011
- * @date last modification: Thu Jun 12 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief A very complicated structure
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh_struct.hh"
#include "structural_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_2
using namespace akantu;
//Linear load function
static void lin_load(double * position, double * load,
__attribute__ ((unused)) Real * normal, __attribute__ ((unused)) UInt surface_id){
memset(load,0,sizeof(Real)*3);
if(position[1]>=0.-Math::getTolerance()) {
if ((position[0]<=10.)){
load[1]= -100;
} else if (position[0]<=20.){
load[1]= -70;
}
}
}
int main(int argc, char *argv[]){
initialize(argc, argv);
Mesh beams(2);
debug::setDebugLevel(dblWarning);
/* -------------------------------------------------------------------------- */
// Defining the mesh
akantu::MeshIOMSHStruct mesh_io;
mesh_io.read("complicated.msh", beams);
/* -------------------------------------------------------------------------- */
// Defining the material
const akantu::ElementType type = akantu::_bernoulli_beam_2;
akantu::StructuralMechanicsModel model(beams);
StructuralMaterial mat1;
mat1.E=3e10;
mat1.I=0.0025;
mat1.A=0.01;
model.addMaterial(mat1);
StructuralMaterial mat2 ;
mat2.E=3e10;
mat2.I=0.003125;
mat2.A=0.01;
model.addMaterial(mat2);
/* -------------------------------------------------------------------------- */
// Defining the forces
model.initFull();
UInt nb_element = beams.getNbElement(type);
for (unsigned int i = 0; i < nb_element; ++i) {
model.getElementMaterial(type)(i,0) = beams.getData<UInt>("tag_0", type)(i,0) - 1;
}
Array<Real> & forces = model.getForce();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
forces.clear();
displacement.clear();
model.computeForcesFromFunction<_bernoulli_beam_2>(lin_load, akantu::_bft_traction);
/* -------------------------------------------------------------------------- */
// Defining the boundary conditions
boundary(0,0) = true;
boundary(0,1) = true;
boundary(3,0) = true;
boundary(3,1) = true;
boundary(4,0) = true;
boundary(4,1) = true;
boundary(4,2) = true;
boundary(5,0) = true;
boundary(5,1) = true;
boundary(5,2) = true;
boundary(2,1) = true;
boundary(2,0) = true;
boundary(1,1) = true;
boundary(1,0) = true;
/* -------------------------------------------------------------------------- */
// Solve
Real error;
model.assembleStiffnessMatrix();
model.getStiffnessMatrix().saveMatrix("Kb.mtx");
UInt count = 0;
model.addDumpFieldVector("displacement");
model.addDumpField("rotation");
model.addDumpField("force");
model.addDumpField("momentum");
do {
if(count != 0) std::cerr << count << " - " << error << std::endl;
model.updateResidual();
model.solve();
count++;
} while (!model.testConvergenceIncrement(1e-10, error) && count < 10);
std::cerr << count << " - " << error << std::endl;
/* -------------------------------------------------------------------------- */
// Post-Processing
model.computeStresses();
model.getStiffnessMatrix().saveMatrix("Ka.mtx");
std::cout<< " x1 = " << displacement(1,2) << std::endl;
std::cout<< " x2 = " << displacement(2,2) << std::endl;
model.dump();
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1.cc
index 3b11060ac..a981fd0f3 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1.cc
@@ -1,187 +1,188 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Fri Jul 15 2011
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Computation of the analytical exemple 1.1 in the TGC vol 6
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "structural_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_2
using namespace akantu;
//Linear load function
static void lin_load(double * position, double * load,
__attribute__ ((unused)) Real * normal,
__attribute__ ((unused)) UInt surface_id){
memset(load,0,sizeof(Real)*3);
if (position[0]<=10){
load[1]= -6000;
}
}
int main(int argc, char *argv[]){
initialize(argc, argv);
debug::setDebugLevel(dblWarning);
/* -------------------------------------------------------------------------- */
// Defining the mesh
Mesh beams(2);
UInt nb_nodes=3;
UInt nb_nodes_1=1;
UInt nb_nodes_2=nb_nodes-nb_nodes_1 - 1;
UInt nb_element=nb_nodes-1;
Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
nodes.resize(nb_nodes);
beams.addConnectivityType(_bernoulli_beam_2);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_2));
connectivity.resize(nb_element);
for(UInt i=0; i<nb_nodes; ++i) {
nodes(i,1)=0;
}
for (UInt i = 0; i < nb_nodes_1; ++i) {
nodes(i,0)=10.*i/((Real)nb_nodes_1);
}
nodes(nb_nodes_1,0)=10;
for (UInt i = 0; i < nb_nodes_2; ++i) {
nodes(nb_nodes_1 + i + 1,0)=10+ 8.*(i+1)/((Real)nb_nodes_2);
}
for(UInt i=0; i<nb_element; ++i) {
connectivity(i,0)=i;
connectivity(i,1)=i+1;
}
/* -------------------------------------------------------------------------- */
// Defining the materials
// akantu::ElementType type = akantu::_bernoulli_beam_2;
StructuralMechanicsModel model(beams);
StructuralMaterial mat1;
mat1.E=3e10;
mat1.I=0.0025;
mat1.A=0.01;
model.addMaterial(mat1);
StructuralMaterial mat2 ;
mat2.E=3e10;
mat2.I=0.00128;
mat2.A=0.01;
model.addMaterial(mat2);
/* -------------------------------------------------------------------------- */
// Defining the forces
model.initFull();
const Real M = -3600; // Momentum at 3
Array<Real> & forces = model.getForce();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
const Array<Real> & N_M = model.getStress(_bernoulli_beam_2);
Array<UInt> & element_material = model.getElementMaterial(_bernoulli_beam_2);
forces.clear();
displacement.clear();
for (UInt i = 0; i < nb_nodes_2; ++i) {
element_material(i+nb_nodes_1)=1;
}
forces(nb_nodes-1,2) += M;
model.computeForcesFromFunction<_bernoulli_beam_2>(lin_load, akantu::_bft_traction);
/* -------------------------------------------------------------------------- */
// Defining the boundary conditions
boundary(0,0) = true;
boundary(0,1) = true;
boundary(0,2) = true;
boundary(nb_nodes_1,1) = true;
boundary(nb_nodes-1,1) = true;
/* -------------------------------------------------------------------------- */
// Solve
Real error;
model.assembleStiffnessMatrix();
model.getStiffnessMatrix().saveMatrix("Kb.mtx");
UInt count = 0;
model.addDumpField("displacement");
model.addDumpField("rotation");
model.addDumpField("force");
model.addDumpField("momentum");
do {
if(count != 0) std::cerr << count << " - " << error << std::endl;
model.updateResidual();
model.solve();
count++;
} while (!model.testConvergenceIncrement(1e-10, error) && count < 10);
std::cerr << count << " - " << error << std::endl;
/* -------------------------------------------------------------------------- */
// Post-Processing
model.computeStresses();
model.getStiffnessMatrix().saveMatrix("Ka.mtx");
std::cout<< " d1 = " << displacement(nb_nodes_1,2) << std::endl;
std::cout<< " d2 = " << displacement(nb_nodes-1,2) << std::endl;
std::cout<< " M1 = " << N_M(0,1) << std::endl;
std::cout<< " M2 = " << N_M(2*(nb_nodes-2),1) << std::endl;
model.dump();
finalize();
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1_y.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1_y.cc
index 22b635809..5c2fcd21b 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1_y.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1_y.cc
@@ -1,179 +1,179 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1_y.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test for _bernouilli_beam_2D
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "structural_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_2
using namespace akantu;
//Linear load function
static void lin_load(double * position, double * load,
__attribute__ ((unused)) Real * normal, __attribute__ ((unused)) UInt surface_id){
memset(load,0,sizeof(Real)*3);
if (position[1]<=10){
load[0]= 6000;
}
}
int main(int argc, char *argv[]){
initialize(argc, argv);
Mesh beams(2);
debug::setDebugLevel(dblWarning);
/* -------------------------------------------------------------------------- */
// Defining the mesh
UInt nb_nodes=3;
UInt nb_nodes_1=1;
UInt nb_nodes_2=nb_nodes-nb_nodes_1 - 1;
UInt nb_element=nb_nodes-1;
Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
nodes.resize(nb_nodes);
beams.addConnectivityType(_bernoulli_beam_2);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_2));
connectivity.resize(nb_element);
for(UInt i=0; i<nb_nodes; ++i) {
nodes(i,0)=0;
}
for (UInt i = 0; i < nb_nodes_1; ++i) {
nodes(i,1)=10.*i/((Real)nb_nodes_1);
}
nodes(nb_nodes_1,1)=10;
for (UInt i = 0; i < nb_nodes_2; ++i) {
nodes(nb_nodes_1 + i + 1,1)=10+ 8.*(i+1)/((Real)nb_nodes_2);
}
for(UInt i=0; i<nb_element; ++i) {
connectivity(i,0)=i;
connectivity(i,1)=i+1;
}
akantu::MeshIOMSH mesh_io;
mesh_io.write("b_beam_2.msh", beams);
/* -------------------------------------------------------------------------- */
// Defining the materials
akantu::StructuralMechanicsModel model(beams);
StructuralMaterial mat1;
mat1.E=3e10;
mat1.I=0.0025;
mat1.A=0.01;
model.addMaterial(mat1);
StructuralMaterial mat2 ;
mat2.E=3e10;
mat2.I=0.00128;
mat2.A=0.01;
model.addMaterial(mat2);
/* -------------------------------------------------------------------------- */
// Defining the forces
model.initFull();
const Real M = -3600; // Momentum at 3
Array<Real> & forces = model.getForce();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
const Array<Real> & N_M = model.getStress(_bernoulli_beam_2);
Array<UInt> & element_material = model.getElementMaterial(_bernoulli_beam_2);
for (UInt i = 0; i < nb_nodes_2; ++i) {
element_material(i+nb_nodes_1)=1;
}
forces(nb_nodes-1,2) += M;
model.computeForcesFromFunction<_bernoulli_beam_2>(lin_load, akantu::_bft_traction);
/* -------------------------------------------------------------------------- */
// Defining the boundary conditions
boundary(0,0) = true;
boundary(0,1) = true;
boundary(0,2) = true;
boundary(nb_nodes_1,0) = true;
boundary(nb_nodes-1,0) = true;
/* -------------------------------------------------------------------------- */
// Solve
Real error;
model.assembleStiffnessMatrix();
model.getStiffnessMatrix().saveMatrix("Kb.mtx");
UInt count = 0;
model.addDumpField("displacememt");
model.addDumpField("rotation");
model.addDumpField("force");
model.addDumpField("momentum");
do {
if(count != 0) std::cerr << count << " - " << error << std::endl;
model.updateResidual();
model.solve();
count++;
} while (!model.testConvergenceIncrement(1e-10, error) && count < 10);
std::cerr << count << " - " << error << std::endl;
/* -------------------------------------------------------------------------- */
// Post-Processing
model.computeStresses();
model.getStiffnessMatrix().saveMatrix("Ka.mtx");
std::cout<< " d1 = " << displacement(nb_nodes_1,2) << std::endl;
std::cout<< " d2 = " << displacement(nb_nodes-1,2) << std::endl;
std::cout<< " M1 = " << N_M(0,1) << std::endl;
std::cout<< " M2 = " << N_M(2*(nb_nodes-2),1) << std::endl;
model.dump();
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_xy.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_xy.cc
index 84a353249..e486cf23c 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_xy.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_xy.cc
@@ -1,195 +1,195 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_xy.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test for _bernouilli_beam_3D
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "structural_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_3
using namespace akantu;
//Linear load function
static void lin_load(double * position, double * load,
__attribute__ ((unused)) Real * normal, __attribute__ ((unused)) UInt surface_id){
memset(load,0,sizeof(Real)*6);
if (position[0]<=10){
load[1]= -6000;
}
}
int main(int argc, char *argv[]){
initialize(argc, argv);
Mesh beams(3);
debug::setDebugLevel(dblWarning);
std::cout<<"Initialisation"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the mesh
UInt nb_nodes=3;
UInt nb_nodes_1=1;
UInt nb_nodes_2=nb_nodes-nb_nodes_1 - 1;
UInt nb_element=nb_nodes-1;
Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
nodes.resize(nb_nodes);
beams.addConnectivityType(_bernoulli_beam_3);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_3));
connectivity.resize(nb_element);
beams.initNormals();
Array<Real> & normals = const_cast<Array<Real> &>(beams.getNormals(_bernoulli_beam_3));
normals.resize(nb_element);
for(UInt i=0; i<nb_nodes; ++i) {
nodes(i,1)=0;
nodes(i,2)=0;
}
for (UInt i = 0; i < nb_nodes_1; ++i) {
nodes(i,0)=10.*i/((Real)nb_nodes_1);
}
nodes(nb_nodes_1,0) = 10;
for (UInt i = 0; i < nb_nodes_2; ++i) {
nodes(nb_nodes_1 + i + 1,0)=10+ 8.*(i+1)/((Real)nb_nodes_2);
}
for(UInt i=0; i<nb_element; ++i) {
connectivity(i,0)=i;
connectivity(i,1)=i+1;
normals(i,0)=0;
normals(i,1)=0;
normals(i,2)=1;
}
akantu::MeshIOMSH mesh_io;
mesh_io.write("b_beam_3.msh", beams);
std::cout<<"Mesh definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the materials
akantu::StructuralMechanicsModel model(beams);
StructuralMaterial mat1;
mat1.E=3e10;
mat1.Iz=0.0025;
mat1.A=0.01;
mat1.Iy=0.00128;
mat1.GJ=0.00128;
model.addMaterial(mat1);
StructuralMaterial mat2 ;
mat2.E=3e10;
mat2.Iz=0.00128;
mat2.A=0.01;
mat2.Iy=0.0025;
mat2.GJ=0.0025;
model.addMaterial(mat2);
std::cout<<"Material Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the forces
model.initFull();
const Real M = -3600; // Momentum at 3
Array<Real> & forces = model.getForce();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
const Array<Real> & N_M = model.getStress(_bernoulli_beam_3);
Array<UInt> & element_material = model.getElementMaterial(_bernoulli_beam_3);
for (UInt i = 0; i < nb_nodes_2; ++i) {
element_material(i+nb_nodes_1)=1;
}
forces(nb_nodes-1,5) += M;
model.computeForcesFromFunction<_bernoulli_beam_3>(lin_load, akantu::_bft_traction);
std::cout<<"Force Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the boundary conditions
boundary(0,0) = true;
boundary(0,1) = true;
boundary(0,2) = true;
boundary(0,3) = true;
boundary(0,4) = true;
boundary(0,5) = true;
boundary(nb_nodes_1,1) = true;
boundary(nb_nodes-1,1) = true;
std::cout<<"BC Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Solve
Real error;
model.assembleStiffnessMatrix();
std::cout<<"Assemble Done"<<std::endl;
model.getStiffnessMatrix().saveMatrix("Kbx.mtx");
UInt count = 0;
std::cout<<"Matrix saved"<<std::endl;
do {
if(count != 0) std::cerr << count << " - " << error << std::endl;
model.updateResidual();
model.solve();
count++;
} while (!model.testConvergenceIncrement(1e-10, error) && count < 10);
std::cerr << count << " - " << error << std::endl;
/* -------------------------------------------------------------------------- */
// Post-Processing
model.computeStresses();
model.getStiffnessMatrix().saveMatrix("Kax.mtx");
std::cout<< " d1 = " << displacement(nb_nodes_1,5) << std::endl;
std::cout<< " d2 = " << displacement(nb_nodes-1,5) << std::endl;
std::cout<< " M1 = " << N_M(0,1) << std::endl;
std::cout<< " M2 = " << N_M(2*(nb_nodes-2),1) << std::endl;
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_zy.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_zy.cc
index 284be87d9..d16a5b2df 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_zy.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_zy.cc
@@ -1,206 +1,206 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_zy.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test for _bernouilli_beam_3D
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "structural_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_3
using namespace akantu;
//Linear load function
static void lin_load(double * position, double * load,
__attribute__ ((unused)) Real * normal, __attribute__ ((unused)) UInt surface_id){
memset(load,0,sizeof(Real)*3);
if (position[2]<=10){
load[1]= 6000;
}
}
int main(int argc, char *argv[]){
initialize(argc, argv);
Mesh beams(3);
debug::setDebugLevel(dblWarning);
std::cout<<"Initialisation"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the mesh
UInt nb_nodes=3;
UInt nb_nodes_1=1;
UInt nb_nodes_2=nb_nodes-nb_nodes_1 - 1;
UInt nb_element=nb_nodes-1;
Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
nodes.resize(nb_nodes);
beams.addConnectivityType(_bernoulli_beam_3);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_3));
connectivity.resize(nb_element);
beams.initNormals();
Array<Real> & normals = const_cast<Array<Real> &>(beams.getNormals(_bernoulli_beam_3));
normals.resize(nb_element);
for(UInt i=0; i<nb_nodes; ++i) {
nodes(i,1)=0;
nodes(i,0)=0;
}
for (UInt i = 0; i < nb_nodes_1; ++i) {
nodes(i,2)=10.*i/((Real)nb_nodes_1);
}
nodes(nb_nodes_1,2)=10;
for (UInt i = 0; i < nb_nodes_2; ++i) {
nodes(nb_nodes_1 + i + 1,2)=10+ 8.*(i+1)/((Real)nb_nodes_2);
}
for(UInt i=0; i<nb_element; ++i) {
connectivity(i,0)=i;
connectivity(i,1)=i+1;
normals(i,0)=1;
normals(i,1)=0;
normals(i,2)=0;
}
akantu::MeshIOMSH mesh_io;
mesh_io.write("b_beam_3.msh", beams);
std::cout<<"Mesh definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the materials
akantu::StructuralMechanicsModel model(beams);
StructuralMaterial mat1;
mat1.E=3e10;
mat1.Iz=0.0025;
mat1.A=0.01;
mat1.Iy=0.00128;
mat1.GJ=0.00128;
model.addMaterial(mat1);
StructuralMaterial mat2 ;
mat2.E=3e10;
mat2.Iz=0.00128;
mat2.A=0.01;
mat2.Iy=0.0025;
mat2.GJ=0.0025;
model.addMaterial(mat2);
std::cout<<"Material Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the forces
model.initFull();
const Real M = -3600; // Momentum at 3
Array<Real> & forces = model.getForce();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
const Array<Real> & N_M = model.getStress(_bernoulli_beam_3);
Array<UInt> & element_material = model.getElementMaterial(_bernoulli_beam_3);
forces.clear();
displacement.clear();
for (UInt i = 0; i < nb_nodes_2; ++i) {
element_material(i+nb_nodes_1)=1;
}
forces(nb_nodes-1,3) += M;
model.computeForcesFromFunction<_bernoulli_beam_3>(lin_load, akantu::_bft_traction);
std::cout<<"Force Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the boundary conditions
boundary(0,0) = true;
boundary(0,1) = true;
boundary(0,2) = true;
boundary(0,3) = true;
boundary(0,4) = true;
boundary(0,5) = true;
boundary(nb_nodes_1,1) = true;
boundary(nb_nodes-1,1) = true;
std::cout<<"BC Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Solve
Real error;
model.assembleStiffnessMatrix();
std::cout<<"Assemble Done"<<std::endl;
model.getStiffnessMatrix().saveMatrix("Kbz.mtx");
UInt count = 0;
std::cout<<"Matrix saved"<<std::endl;
model.addDumpField("displacememt");
model.addDumpField("rotation");
model.addDumpField("force");
model.addDumpField("momentum");
do {
if(count != 0) std::cerr << count << " - " << error << std::endl;
model.updateResidual();
model.solve();
count++;
} while (!model.testConvergenceIncrement(1e-10, error) && count < 10);
std::cerr << count << " - " << error << std::endl;
/* -------------------------------------------------------------------------- */
// Post-Processing
model.computeStresses();
model.getStiffnessMatrix().saveMatrix("Kaz.mtx");
std::cout<< " d1 = " << displacement(nb_nodes_1,3) << std::endl;
std::cout<< " d2 = " << displacement(nb_nodes-1,3) << std::endl;
std::cout<< " M1 = " << N_M(0,1) << std::endl;
std::cout<< " M2 = " << N_M(2*(nb_nodes-2),1) << std::endl;
model.dump();
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exercice_12_10_13.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exercice_12_10_13.cc
index 926502826..7dd6f52d0 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exercice_12_10_13.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3_exercice_12_10_13.cc
@@ -1,183 +1,183 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_3_exercice_12_10_13.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test for _bernouilli_beam_3D
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "structural_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_3
using namespace akantu;
//Linear load function
static void lin_load(double * position, double * load,
__attribute__ ((unused)) Real * normal, __attribute__ ((unused)) UInt surface_id){
memset(load,0,sizeof(Real)*6);
if (position[0]==1){
load[2]= -60.;
}
}
int main(int argc, char *argv[]){
initialize(argc, argv);
Mesh beams(3);
debug::setDebugLevel(dblWarning);
std::cout<<"Initialisation"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the mesh
UInt nb_nodes=4;
UInt nb_element=nb_nodes-1;
Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
nodes.resize(nb_nodes);
beams.addConnectivityType(_bernoulli_beam_3);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_3));
connectivity.resize(nb_element);
beams.initNormals();
Array<Real> & normals = const_cast<Array<Real> &>(beams.getNormals(_bernoulli_beam_3));
normals.resize(nb_element);
nodes(0,0)=0.;
nodes(0,1)=0.;
nodes(0,2)=0.;
nodes(1,0)=0.;
nodes(1,1)=0.5;
nodes(1,2)=0.;
nodes(2,0)=1.;
nodes(2,1)=0.5;
nodes(2,2)=0.;
nodes(3,0)=1.;
nodes(3,1)=0.;
nodes(3,2)=0.;
for (UInt i=0; i<nb_element; ++i) {
connectivity(i,0)=i;
connectivity(i,1)=i+1;
normals(i,0)=0.;
normals(i,1)=0.;
normals(i,2)=1.;
}
akantu::MeshIOMSH mesh_io;
mesh_io.write("b_beam_3_12_10_13.msh", beams);
std::cout<<"Mesh definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the materials
akantu::StructuralMechanicsModel model(beams);
StructuralMaterial mat1;
mat1.E=2.05e11;
mat1.Iz=2.8e-9;
mat1.A=1.33e-4;
mat1.Iy=2.8e-9;
mat1.GJ=220.77;
model.addMaterial(mat1);
std::cout<<"Material Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the forces
model.initFull();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
model.computeForcesFromFunction<_bernoulli_beam_3>(lin_load, akantu::_bft_traction);
std::cout<<"Force Definition"<<std::endl;
//forces(1,2)=-15;
//forces(0,2)=-15;
//forces(0,3)=-1.25;
//forces(1,4)=1.25;
/* -------------------------------------------------------------------------- */
// Defining the boundary conditions
boundary(0,0) = true;
boundary(0,1) = true;
boundary(0,2) = true;
boundary(0,3) = true;
boundary(0,4) = true;
boundary(0,5) = true;
std::cout<<"BC Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Solve
Real error;
model.assembleStiffnessMatrix();
std::cout<<"Assemble Done"<<std::endl;
model.getStiffnessMatrix().saveMatrix("Kbx.mtx");
UInt count = 0;
std::cout<<"Matrix saved"<<std::endl;
model.addDumpField("displacement");
model.addDumpField("rotation");
model.addDumpField("force");
model.addDumpField("momentum");
do {
if(count != 0) std::cerr << count << " - " << error << std::endl;
model.updateResidual();
model.solve();
count++;
} while (!model.testConvergenceIncrement(1e-10, error) && count < 10);
std::cerr << count << " - " << error << std::endl;
/* -------------------------------------------------------------------------- */
// Post-Processing
model.computeStresses();
model.getStiffnessMatrix().saveMatrix("Kax.mtx");
std::cout<< " wA = " << displacement(3,2) << std::endl;
std::cout<< " TethayB = " << displacement(2,4) << std::endl;
model.dump();
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_dynamics.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_dynamics.cc
index 27af14787..484e6e148 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_dynamics.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_dynamics.cc
@@ -1,195 +1,195 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_dynamics.cc
*
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
*
* @date creation: Mon Jul 07 2014
- * @date last modification: Mon Jul 07 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test for _bernouilli_beam in dynamic
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh_struct.hh"
#include "structural_mechanics_model.hh"
#include "material.hh"
#include <iostream>
using namespace akantu;
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_2
static Real analytical_solution(Real time, Real L, Real rho, Real E, Real A, Real I, Real F) {
Real omega = M_PI*M_PI/L/L*sqrt(E*I/rho);
Real sum = 0.;
UInt i=5;
for(UInt n=1; n <= i; n +=2) {
sum += (1. - cos(n*n*omega*time))/pow(n, 4);
}
return 2.*F*pow(L, 3)/pow(M_PI, 4)/E/I*sum;
}
//load
const Real F = 0.5e4;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]){
initialize(argc, argv);
Mesh beams(2);
debug::setDebugLevel(dblWarning);
const ElementType type = _bernoulli_beam_2;
/* -------------------------------------------------------------------------- */
// Mesh
UInt nb_element = 8;
UInt nb_nodes = nb_element + 1;
Real total_length = 10.;
Real length = total_length/nb_element;
Real heigth = 1.;
Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
nodes.resize(nb_nodes);
beams.addConnectivityType(type);
Array<UInt> &connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(type));
connectivity.resize(nb_element);
beams.initNormals();
Array<Real> & normals = const_cast<Array<Real> &>(beams.getNormals(type));
normals.resize(nb_element);
for (UInt i = 0; i < nb_nodes; ++i){
nodes(i,0) = i * length;
nodes(i,1) = 0;
}
for (UInt i = 0; i < nb_element; ++i){
connectivity(i,0) = i;
connectivity(i,1) = i+1;
}
/* -------------------------------------------------------------------------- */
// Materials
StructuralMechanicsModel model(beams);
StructuralMaterial mat1;
mat1.E = 120e6;
mat1.rho = 1000;
mat1.A = heigth;
mat1.I = heigth*heigth*heigth/12;
model.addMaterial(mat1);
/* -------------------------------------------------------------------------- */
// Forces
// model.initFull();
model.initFull(StructuralMechanicsModelOptions(_implicit_dynamic));
const Array<Real> &position = beams.getNodes();
Array<Real> &forces = model.getForce();
Array<Real> &displacement = model.getDisplacement();
Array<bool> &boundary = model.getBlockedDOFs();
UInt node_to_print = -1;
forces.clear();
displacement.clear();
// boundary.clear();
//model.getElementMaterial(type)(i,0) = 0;
//model.getElementMaterial(type)(i,0) = 1;
for (UInt i = 0; i < nb_element; ++i) {
model.getElementMaterial(type)(i,0) = 0;
}
for (UInt n =0; n<nb_nodes; ++n){
Real x = position(n, 0);
// Real y = position(n, 1);
if (Math::are_float_equal(x, total_length/2.)){
forces(n,1) = F;
node_to_print = n;
}
}
std::ofstream pos;
pos.open("position.csv");
if(!pos.good()) {
std::cerr << "Cannot open file" << std::endl;
exit(EXIT_FAILURE);
}
pos << "id,time,position,solution" << std::endl;
// model.computeForcesFromFunction<type>(load, _bft_traction)
/* -------------------------------------------------------------------------- */
// Boundary conditions
// true ~ displacement is blocked
boundary(0,0) = true;
boundary(0,1) = true;
boundary(nb_nodes-1,1) = true;
/* -------------------------------------------------------------------------- */
// "Solve"
Real time = 0;
model.assembleStiffnessMatrix();
model.assembleMass();
model.dump();
model.getStiffnessMatrix().saveMatrix("K.mtx");
model.getMassMatrix().saveMatrix("M.mt");
Real time_step = 1e-4;
model.setTimeStep(time_step);
std::cout << "Time" << " | " << "Mid-Span Displacement" << std::endl;
/// time loop
for (UInt s = 1; time < 0.64; ++s) {
model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(1e-12, 1000);
pos << s << "," << time << "," << displacement(node_to_print, 1) << "," << analytical_solution(s*time_step, total_length, mat1.rho, mat1.E, mat1.A, mat1.I, F) << std::endl;
// pos << s << "," << time << "," << displacement(node_to_print, 1) << "," << analytical_solution(s*time_step) << std::endl;
time += time_step;
if(s % 100 == 0)
std::cout << time << " | " << displacement(node_to_print, 1) << std::endl;
model.dump();
}
pos.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc
index 6789ca1e7..a9a18f2ef 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc
@@ -1,252 +1,252 @@
/**
* @file test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc
*
* @author Damien Spielmann <damien.spielmann@epfl.ch>
*
- * @date creation: Fri Jul 04 2014
- * @date last modification: Fri Jul 04 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief patch test exemple 4.5.5 c.f. modelisation des structures par éléments finis J.-L. Batoz/G Dhatt
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include <limits>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "structural_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#define TYPE _kirchhoff_shell
using namespace akantu;
int main(int argc, char *argv[]){
initialize(argc, argv);
Mesh shell(3);
debug::setDebugLevel(dblWarning);
std::cout<<"Initialisation"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the mesh
UInt nb_nodes=5;
UInt nb_element=4;
Array<Real> & nodes = const_cast<Array<Real> &>(shell.getNodes());
nodes.resize(nb_nodes);
Real a=20.;
Real b=10.;
nodes(0,0)=0.;
nodes(0,1)=0.;
nodes(0,2)=0.;
nodes(1,0)=2*a;
nodes(1,1)=0.;
nodes(1,2)=0.;
nodes(2,0)=0.;
nodes(2,1)=2*b;
nodes(2,2)=0.;
nodes(3,0)=2*a;
nodes(3,1)=2*b;
nodes(3,2)=0.;
nodes(4,0)=15.;
nodes(4,1)=15.;
nodes(4,2)=0.;
shell.addConnectivityType(TYPE);
Array<UInt> & connectivity = const_cast<Array<UInt> &>(shell.getConnectivity(TYPE));
connectivity.resize(nb_element);
connectivity(0,0)=1;
connectivity(0,1)=3;
connectivity(0,2)=4;
connectivity(1,0)=3;
connectivity(1,1)=2;
connectivity(1,2)=4;
connectivity(2,0)=2;
connectivity(2,1)=4;
connectivity(2,2)=0;
connectivity(3,0)=0;
connectivity(3,1)=1;
connectivity(3,2)=4;
akantu::MeshIOMSH mesh_io;
mesh_io.write("b_beam_3_12_10_13.msh", shell);
std::cout<<"Mesh definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the materials
akantu::StructuralMechanicsModel model(shell); // ä döfinir
StructuralMaterial mat1;
mat1.E=1000;
mat1.nu=0.3;
mat1.t=1;
model.addMaterial(mat1);
std::cout<<"Material Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Defining the deplacement
model.initFull();
// Array<Real> & forces = model.getForce();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
displacement(0,0)=0;
displacement(0,1)=0;
displacement(0,2)=0;
displacement(0,3)=0;
displacement(0,4)=0;
displacement(1,0)=0;
displacement(1,1)=0;
displacement(1,2)=-800;
displacement(1,3)=-40;
displacement(1,4)=-20;
displacement(2,0)=0;
displacement(2,1)=0;
displacement(2,2)=-200;
displacement(2,3)=-10;
displacement(2,4)=-20;
displacement(3,0)=0;
displacement(3,1)=0;
displacement(3,2)=-1400;
displacement(3,3)=-50;
displacement(3,4)=-40;
/*displacement(4,0)=0;
displacement(4,1)=0;*/
/* displacement(4,2)=;
displacement(4,3)=;
displacement(4,4)=;*/
/* -------------------------------------------------------------------------- */
// Defining the boundary conditions
boundary(0,0) = true;
boundary(0,1) = true;
boundary(0,2) = true;
boundary(0,3) = true;
boundary(0,4) = true;
boundary(0,5) = true;
boundary(1,0) = true;
boundary(1,1) = true;
boundary(1,2) = true;
boundary(1,3) = true;
boundary(1,4) = true;
boundary(1,5) = true;
boundary(2,0) = true;
boundary(2,1) = true;
boundary(2,2) = true;
boundary(2,3) = true;
boundary(2,4) = true;
boundary(2,5) = true;
boundary(3,0) = true;
boundary(3,1) = true;
boundary(3,2) = true;
boundary(3,3) = true;
boundary(3,4) = true;
boundary(3,5) = true;
// boundary(4,0) = true;
// boundary(4,1) = true;
// boundary(4,2) = true;
// boundary(4,3) = true;
// boundary(4,4) = true;
boundary(4,5) = true;
std::cout<<"BC Definition"<<std::endl;
/* -------------------------------------------------------------------------- */
// Solve
Real error;
model.assembleStiffnessMatrix();
std::cout<<"Assemble Done"<<std::endl;
model.getStiffnessMatrix().saveMatrix("K_4_5_5.mtx");
UInt count = 0;
std::cout<<"Matrix saved"<<std::endl;
model.addDumpField("displacement");
model.addDumpField("rotation");
model.addDumpField("force");
model.addDumpField("momentum");
do {
model.updateResidual();
model.solve();
count++;
} while (!model.testConvergenceIncrement(1e-10, error) && count < 10);
/* -------------------------------------------------------------------------- */
// Post-Processing
model.computeStresses();
//const SparseMatrix = model.getStiffnessMatrix();
std::cout<< "u = " << displacement(4,0) << std::endl;
std::cout<< "v = " << displacement(4,1) << std::endl;
std::cout<< "w5 = " << displacement(4,2) << std::endl;
std::cout<< "betax = " << displacement(4,3) << std::endl;
std::cout<< "betay = " << displacement(4,4) << std::endl;
std::cout<< "betaz = " << displacement(4,5) << std::endl;
//model.dump();
}
diff --git a/test/test_python_interface/CMakeLists.txt b/test/test_python_interface/CMakeLists.txt
index 47fe8922b..dead161f3 100644
--- a/test/test_python_interface/CMakeLists.txt
+++ b/test/test_python_interface/CMakeLists.txt
@@ -1,34 +1,36 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Fabian Barras <fabian.barras@epfl.ch>
#
-# @date creation: Tue Jan 5 2016
+# @date creation: Fri Sep 03 2010
+# @date last modification: Wed Jan 06 2016
#
# @brief Python Interface tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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/>.
#
#===============================================================================
register_test(test_multiple_init
SCRIPT test_multiple_init.py
PACKAGE python_interface
FILES_TO_COPY input_test.dat mesh_dcb_2d.geo
)
diff --git a/test/test_solver/CMakeCache.txt b/test/test_solver/CMakeCache.txt
index 44fc15c46..52167b39b 100644
--- a/test/test_solver/CMakeCache.txt
+++ b/test/test_solver/CMakeCache.txt
@@ -1,40 +1,68 @@
+#===============================================================================
+# @file CMakeCache.txt
+#
+#
+# @date creation: Wed Dec 16 2015
+#
+# @brief Test for solvers
+#
+# @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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
# This is the CMakeCache file.
# For build in directory: /home/cubaramo/akantu/test/test_solver
# It was generated by CMake: /usr/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
########################
# INTERNAL cache entries
########################
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/cubaramo/akantu/test/test_solver
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=8
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=12
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
//Path to cache edit program executable.
CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/ccmake
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/usr/share/cmake-2.8
diff --git a/test/test_solver/CMakeLists.txt b/test/test_solver/CMakeLists.txt
index 130c89133..dffd68b09 100644
--- a/test/test_solver/CMakeLists.txt
+++ b/test/test_solver/CMakeLists.txt
@@ -1,90 +1,91 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Dec 13 2010
-# @date last modification: Tue Nov 06 2012
+# @date creation: Fri Sep 03 2010
+# @date last modification: Wed Dec 16 2015
#
# @brief configuration for solver tests
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_solver_mesh triangle.geo 2 1)
add_mesh(test_matrix_mesh square.geo 2 1)
add_mesh(test_solver_petsc_mesh 1D_bar.geo 1 1)
register_test(test_sparse_matrix_profile
SOURCES test_sparse_matrix_profile.cc
DEPENDS test_solver_mesh
PACKAGE implicit
)
register_test(test_sparse_matrix_assemble
SOURCES test_sparse_matrix_assemble.cc
DEPENDS test_solver_mesh
PACKAGE implicit
)
register_test(test_sparse_matrix_product
SOURCES test_sparse_matrix_product.cc
FILES_TO_COPY bar.msh
PACKAGE implicit
)
register_test(test_petsc_matrix_profile
SOURCES test_petsc_matrix_profile.cc
DEPENDS test_matrix_mesh
PACKAGE petsc
)
register_test(test_petsc_matrix_profile_parallel
SOURCES test_petsc_matrix_profile_parallel.cc
DEPENDS test_matrix_mesh
PACKAGE petsc
)
register_test(test_petsc_matrix_diagonal
SOURCES test_petsc_matrix_diagonal.cc
DEPENDS test_solver_mesh
PACKAGE petsc
)
register_test(test_petsc_matrix_apply_boundary
SOURCES test_petsc_matrix_apply_boundary.cc
DEPENDS test_solver_mesh
PACKAGE petsc
)
register_test(test_solver_petsc
SOURCES test_solver_petsc.cc
DEPENDS test_solver_petsc_mesh
PACKAGE petsc
)
register_test(test_solver_petsc_parallel
SOURCES test_solver_petsc.cc
DEPENDS test_solver_petsc_mesh
PACKAGE petsc
)
diff --git a/test/test_solver/test_petsc_matrix_apply_boundary.cc b/test/test_solver/test_petsc_matrix_apply_boundary.cc
index 54cb37117..d691b159d 100644
--- a/test/test_solver/test_petsc_matrix_apply_boundary.cc
+++ b/test/test_solver/test_petsc_matrix_apply_boundary.cc
@@ -1,141 +1,144 @@
/**
- * @file test_petsc_matrix_profile.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Jul 30 12:34:08 2014
+ * @file test_petsc_matrix_apply_boundary.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Mon Oct 13 2014
+ * @date last modification: Wed Oct 28 2015
*
* @brief test the applyBoundary method of the PETScMatrix class
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
/* -------------------------------------------------------------------------- */
#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 "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("triangle.msh");
MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
UInt nb_global_nodes = mesh.getNbGlobalNodes();
dof_synchronizer.initGlobalDOFEquationNumbers();
// fill the matrix with
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(nb_global_nodes * spatial_dimension, _symmetric);
K.buildProfile(mesh, dof_synchronizer, spatial_dimension);
Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1);
Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
Array<Real>::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, spatial_dimension, element_type, ghost_type);
// create petsc matrix
PETScMatrix petsc_matrix(nb_global_nodes * spatial_dimension, _symmetric);
petsc_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
// add stiffness matrix to petsc matrix
petsc_matrix.add(K, 1);
// create boundary array: block all dofs
UInt nb_nodes = mesh.getNbNodes();
Array<bool> boundary = Array<bool>(nb_nodes, spatial_dimension, true);
// apply boundary
petsc_matrix.applyBoundary(boundary);
// test if all entries except the diagonal ones have been zeroed
Real test_passed = 0;
for (UInt i = 0; i < nb_nodes * spatial_dimension; ++i) {
if (dof_synchronizer.isLocalOrMasterDOF(i)) {
for (UInt j = 0; j < nb_nodes * spatial_dimension; ++j) {
if (dof_synchronizer.isLocalOrMasterDOF(j)) {
if (i == j)
test_passed += petsc_matrix(i, j) - 1;
else
test_passed += petsc_matrix(i, j) - 0;
}
}
}
}
if (std::abs(test_passed) > Math::getTolerance()) {
finalize();
return EXIT_FAILURE;
}
delete communicator;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_petsc_matrix_diagonal.cc b/test/test_solver/test_petsc_matrix_diagonal.cc
index dd3eed87d..2d6cd979b 100644
--- a/test/test_solver/test_petsc_matrix_diagonal.cc
+++ b/test/test_solver/test_petsc_matrix_diagonal.cc
@@ -1,147 +1,150 @@
/**
* @file test_petsc_matrix_diagonal.cc
+ *
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Apr 22 09:41:14 2015
+ *
+ * @date creation: Mon Oct 13 2014
+ * @date last modification: Fri Jan 15 2016
*
* @brief test the connectivity is correctly represented in the PETScMatrix
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
/* -------------------------------------------------------------------------- */
#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("triangle.msh");
MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
// 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<IntegratorGauss,ShapeLagrange,_ek_regular>(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<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
Array<Real>::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);
/// check to how many elements each node is connected
CSR<Element> node_to_elem;
MeshUtils::buildNode2Elements(mesh, node_to_elem, spatial_dimension);
/// test the diagonal of the PETSc matrix: the diagonal entries
/// of the PETSc matrix correspond to the number of elements
/// connected to the node of the dof. Note: for an Akantu matrix this is only true for the serial case
Real error = 0.;
/// loop over all diagonal values of the matrix
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
UInt dof = i * spatial_dimension + j;
/// for PETSc matrix only DOFs on the processor and be accessed
if (dof_synchronizer.isLocalOrMasterDOF(dof)) {
UInt global_dof = dof_synchronizer.getDOFGlobalID(dof);
std::cout << "Number of elements connected: " << node_to_elem.getNbCols(i) << std::endl;
std::cout << "K_petsc(" << global_dof << "," << global_dof << ")=" << K_petsc(dof,dof) << std::endl;
error += std::abs(K_petsc(dof, dof) - node_to_elem.getNbCols(i));
}
}
}
if(error > Math::getTolerance() ) {
std::cout << "error in the stiffness matrix!!!" << std::cout;
finalize();
return EXIT_FAILURE;
}
delete communicator;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_petsc_matrix_profile.cc b/test/test_solver/test_petsc_matrix_profile.cc
index bff41dcfd..b4e8c7dbe 100644
--- a/test/test_solver/test_petsc_matrix_profile.cc
+++ b/test/test_solver/test_petsc_matrix_profile.cc
@@ -1,131 +1,134 @@
/**
* @file test_petsc_matrix_profile.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Jul 30 12:34:08 2014
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Mon Oct 13 2014
+ * @date last modification: Tue Apr 28 2015
*
* @brief test the profile generation of the PETScMatrix class
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <fstream>
/* -------------------------------------------------------------------------- */
#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<IntegratorGauss,ShapeLagrange,_ek_regular>(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<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
Array<Real>::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.txt");
/// print the matrix to screen
std::ifstream profile;
profile.open("profile.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_petsc_matrix_profile_parallel.cc b/test/test_solver/test_petsc_matrix_profile_parallel.cc
index 2ec40523c..3e9a6f552 100644
--- a/test/test_solver/test_petsc_matrix_profile_parallel.cc
+++ b/test/test_solver/test_petsc_matrix_profile_parallel.cc
@@ -1,130 +1,133 @@
/**
- * @file test_petsc_matrix_profile.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Wed Jul 30 12:34:08 2014
+ * @file test_petsc_matrix_profile_parallel.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @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 (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <fstream>
/* -------------------------------------------------------------------------- */
#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<IntegratorGauss,ShapeLagrange,_ek_regular>(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<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
Array<Real>::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();
delete communicator;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_solver_petsc.cc b/test/test_solver/test_solver_petsc.cc
index 2ad17899c..114be7dff 100644
--- a/test/test_solver/test_solver_petsc.cc
+++ b/test/test_solver/test_solver_petsc.cc
@@ -1,162 +1,165 @@
/**
* @file test_solver_petsc.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Tue Dec 2 17:17:34 2014
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Mon Oct 13 2014
+ * @date last modification: Wed Oct 28 2015
*
* @brief test the PETSc solver interface
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include <cstdlib>
/* -------------------------------------------------------------------------- */
#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 "solver_petsc.hh"
#include "fe_engine.hh"
#include "dof_synchronizer.hh"
#include "mesh_partition_scotch.hh"
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const ElementType element_type = _segment_2;
const GhostType ghost_type = _not_ghost;
UInt spatial_dimension = 1;
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("1D_bar.msh");
MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
UInt nb_global_nodes = mesh.getNbGlobalNodes();
dof_synchronizer.initGlobalDOFEquationNumbers();
// fill the matrix with
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(nb_global_nodes * spatial_dimension, _symmetric);
K.buildProfile(mesh, dof_synchronizer, spatial_dimension);
Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 0);
for (UInt i = 0; i < nb_dofs_per_element; ++i) {
for (UInt j = 0; j < nb_dofs_per_element; ++j) {
element_input(i, j) = ((i == j) ? 1 : -1);
}
}
Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
Array<Real>::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, spatial_dimension, element_type, ghost_type);
// apply boundary: block first node
const Array<Real> & position = mesh.getNodes();
UInt nb_nodes = mesh.getNbNodes();
Array<bool> boundary = Array<bool>(nb_nodes, spatial_dimension, false);
for (UInt i = 0; i < nb_nodes; ++i) {
if (std::abs(position(i, 0)) < Math::getTolerance() )
boundary(i, 0) = true;
}
K.applyBoundary(boundary);
/// create the PETSc matrix for the solve step
PETScMatrix petsc_matrix(nb_global_nodes * spatial_dimension, _symmetric);
petsc_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
/// copy the stiffness matrix into the petsc matrix
petsc_matrix.add(K, 1);
// initialize internal forces: they are zero because imposed displacement is zero
Array<Real> internal_forces(nb_nodes, spatial_dimension, 0.);
// compute residual: apply nodal force on last node
Array<Real> residual(nb_nodes, spatial_dimension, 0.);
for (UInt i = 0; i < nb_nodes; ++i) {
if (std::abs(position(i, 0) - 10) < Math::getTolerance() )
residual(i, 0) += 2;
}
residual -= internal_forces;
/// initialize solver and solution
Array<Real> solution(nb_nodes, spatial_dimension, 0.);
SolverPETSc solver(petsc_matrix);
solver.initialize();
solver.setOperators();
solver.setRHS(residual);
solver.solve(solution);
/// verify solution
Math::setTolerance(1e-11);
for (UInt i = 0; i < nb_nodes; ++i) {
if (!dof_synchronizer.isPureGhostDOF(i) && !Math::are_float_equal(2 * position(i, 0), solution(i, 0))) {
std::cout << "The solution is not correct!!!!" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
delete communicator;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_sparse_matrix_assemble.cc b/test/test_solver/test_sparse_matrix_assemble.cc
index 7c66a0290..772b4fe15 100644
--- a/test/test_solver/test_sparse_matrix_assemble.cc
+++ b/test/test_solver/test_sparse_matrix_assemble.cc
@@ -1,81 +1,82 @@
/**
* @file test_sparse_matrix_assemble.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief test the assembling method of the SparseMatrix class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <cstdlib>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "sparse_matrix.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
akantu::UInt spatial_dimension = 2;
akantu::Mesh mesh(spatial_dimension);
akantu::MeshIOMSH mesh_io;
mesh_io.read("triangle.msh", mesh);
akantu::UInt nb_nodes = mesh.getNbNodes();
akantu::SparseMatrix sparse_matrix(nb_nodes * spatial_dimension, akantu::_symmetric);
akantu::DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
dof_synchronizer.initGlobalDOFEquationNumbers();
sparse_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
// const akantu::Mesh::ConnectivityTypeList & type_list = mesh.getConnectivityTypeList();
// akantu::Mesh::ConnectivityTypeList::const_iterator it;
// for(it = type_list.begin(); it != type_list.end(); ++it) {
// if(mesh.getSpatialDimension(*it) != spatial_dimension) continue;
// akantu::UInt nb_element = mesh.getNbElement(*it);
// akantu::UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
// akantu::Element element(*it);
// akantu::UInt m = nb_nodes_per_element * spatial_dimension;
// akantu::Array<akantu::Real> local_mat(m, m, 1, "local_mat");
// for(akantu::UInt e = 0; e < nb_element; ++e) {
// element.element = e;
// sparse_matrix.addToMatrix(local_mat.storage(), element, nb_nodes_per_element);
// }
// }
sparse_matrix.saveMatrix("matrix.mtx");
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_sparse_matrix_product.cc b/test/test_solver/test_sparse_matrix_product.cc
index 0b6b5baf8..7a45cdef8 100644
--- a/test/test_solver/test_sparse_matrix_product.cc
+++ b/test/test_solver/test_sparse_matrix_product.cc
@@ -1,147 +1,148 @@
/**
* @file test_sparse_matrix_product.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief test the matrix vector product in parallel
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_partition_scotch.hh"
#include "distributed_synchronizer.hh"
#include "sparse_matrix.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
initialize(argc, argv);
const UInt spatial_dimension = 2;
const UInt nb_dof = 3;
StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
Mesh mesh(spatial_dimension);
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
MeshPartition * partition;
if(prank == 0) {
mesh.read("bar.msh");
std::cout << "Partitioning mesh..." << std::endl;
partition = new akantu::MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
UInt nb_nodes = mesh.getNbNodes();
UInt nb_global_node = mesh.getNbGlobalNodes();
// Array<Int> equation_number(nb_nodes, nb_dof);
// for (UInt n = 0; n < nb_nodes; ++n) {
// UInt real_n = mesh.getNodeGlobalId(n);
// bool is_local_node = !(mesh.isPureGhostNode(n));
// for (UInt d = 0; d < nb_dof; ++d) {
// UInt global_eq_num = (is_local_node ? real_n : nb_global_node + real_n) * nb_dof + d;
// equation_number(n, d) = global_eq_num;
// }
// }
if (prank == 0) std::cout << "Creating a SparseMatrix" << std::endl;
SparseMatrix sparse_matrix(nb_global_node * nb_dof, _symmetric, "matrix");
DOFSynchronizer dof_synchronizer(mesh, nb_dof);
dof_synchronizer.initGlobalDOFEquationNumbers();
sparse_matrix.buildProfile(mesh, dof_synchronizer, nb_dof);
Array<Real> dof_vector(nb_nodes, nb_dof, "vector");
if (prank == 0) std::cout << "Filling the matrix" << std::endl;
UInt nz = sparse_matrix.getNbNonZero();
const Array<Int> & irn = sparse_matrix.getIRN();
const Array<Int> & jcn = sparse_matrix.getJCN();
for (UInt i = 0; i < nz; ++i) {
sparse_matrix.addToMatrix(irn(i) - 1, jcn(i) - 1, 1.);
}
std::stringstream str; str << "Matrix_" << prank << ".mtx";
sparse_matrix.saveMatrix(str.str());
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt d = 0; d < nb_dof; ++d) {
dof_vector(n,d) = 1.;
}
}
if (prank == 0) std::cout << "Computing x = A * x" << std::endl;
dof_vector *= sparse_matrix;
if (prank == 0) std::cout << "Lumping the matrix" << std::endl;
Array<Real> lumped(0,nb_dof);
sparse_matrix.lump(lumped);
if (prank == 0) std::cout << "Gathering the results on proc 0" << std::endl;
if(psize > 1) {
const_cast<DOFSynchronizer &>(sparse_matrix.getDOFSynchronizer()).initScatterGatherCommunicationScheme();
if(prank == 0) {
Array<Real> gathered(0, nb_dof);
Array<Real> lump_gathered(0, nb_dof);
sparse_matrix.getDOFSynchronizer().gather(dof_vector, 0, &gathered);
sparse_matrix.getDOFSynchronizer().gather(lumped, 0, &lump_gathered);
debug::setDebugLevel(dblTest);
std::cout << gathered << std::endl;
std::cout << lump_gathered << std::endl;
debug::setDebugLevel(dblWarning);
} else {
sparse_matrix.getDOFSynchronizer().gather(dof_vector, 0);
sparse_matrix.getDOFSynchronizer().gather(lumped, 0);
}
} else {
debug::setDebugLevel(dblTest);
std::cout << dof_vector << std::endl;
std::cout << lumped << std::endl;
debug::setDebugLevel(dblWarning);
}
finalize();
return 0;
}
diff --git a/test/test_solver/test_sparse_matrix_profile.cc b/test/test_solver/test_sparse_matrix_profile.cc
index 5551cbc0c..17907fd09 100644
--- a/test/test_solver/test_sparse_matrix_profile.cc
+++ b/test/test_solver/test_sparse_matrix_profile.cc
@@ -1,100 +1,101 @@
/**
* @file test_sparse_matrix_profile.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
- * @date last modification: Mon Sep 15 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief test the profile generation of the SparseMatrix class
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <cstdlib>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "sparse_matrix.hh"
#include "dof_synchronizer.hh"
#ifdef AKANTU_USE_SCOTCH
#include "mesh_partition_scotch.hh"
#endif
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
akantu::UInt spatial_dimension = 2;
akantu::Mesh mesh(spatial_dimension);
akantu::MeshIOMSH mesh_io;
mesh_io.read("triangle.msh", mesh);
akantu::SparseMatrix sparse_matrix_hand(10, akantu::_symmetric, "hand");
for(akantu::UInt i = 0; i < 10; ++i) {
sparse_matrix_hand.addToProfile(i, i);
}
sparse_matrix_hand.addToProfile(0,9);
for(akantu::UInt i = 0; i < 10; ++i) {
sparse_matrix_hand.addToMatrix(i, i, i*10);
}
sparse_matrix_hand.addToMatrix(0,9, 100);
sparse_matrix_hand.saveProfile("profile_hand.mtx");
sparse_matrix_hand.saveMatrix("matrix_hand.mtx");
/* ------------------------------------------------------------------------ */
akantu::UInt nb_nodes = mesh.getNbNodes();
akantu::SparseMatrix sparse_matrix(nb_nodes * spatial_dimension, akantu::_symmetric, "mesh");
akantu::DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
dof_synchronizer.initGlobalDOFEquationNumbers();
sparse_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
sparse_matrix.saveProfile("profile.mtx");
/* ------------------------------------------------------------------------ */
#ifdef AKANTU_USE_SCOTCH
mesh_io.write("triangle_breorder.msh", mesh);
akantu::MeshPartition * partition = new akantu::MeshPartitionScotch(mesh, spatial_dimension);
partition->reorder();
delete partition;
akantu::DOFSynchronizer dof_synchronizer_re(mesh, spatial_dimension);
dof_synchronizer_re.initGlobalDOFEquationNumbers();
sparse_matrix.buildProfile(mesh, dof_synchronizer_re, spatial_dimension);
sparse_matrix.saveProfile("profile_reorder.mtx");
mesh_io.write("triangle_reorder.msh", mesh);
#endif
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_sparse_matrix_profile_parallel.cc b/test/test_solver/test_sparse_matrix_profile_parallel.cc
index 492735e37..4ea513a55 100644
--- a/test/test_solver/test_sparse_matrix_profile_parallel.cc
+++ b/test/test_solver/test_sparse_matrix_profile_parallel.cc
@@ -1,112 +1,114 @@
/**
* @file test_sparse_matrix_profile_parallel.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date Mon Feb 07 17:33:51 2011
+ * @date creation: Sun Sep 12 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test the sparse matrix class in parallel
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "mesh.hh"
#include "mesh_io_msh.hh"
#include "mesh_partition_scotch.hh"
#include "communicator.hh"
#include "sparse_matrix.hh"
#include "solver_mumps.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
akantu::initialize(argc, argv);
int dim = 2;
//#ifdef AKANTU_USE_IOHELPER
//akantu::ElementType type = akantu::_triangle_6;
//#endif //AKANTU_USE_IOHELPER
akantu::Mesh mesh(dim);
// akantu::debug::setDebugLevel(akantu::dblDump);
akantu::StaticCommunicator * comm = akantu::StaticCommunicator::getStaticCommunicator();
akantu::Int psize = comm->getNbProc();
akantu::Int prank = comm->whoAmI();
akantu::UInt n = 0;
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
akantu::Communicator * communicator;
if(prank == 0) {
akantu::MeshIOMSH mesh_io;
mesh_io.read("triangle.msh", mesh);
akantu::MeshPartition * partition =
new akantu::MeshPartitionScotch(mesh, dim);
// partition->reorder();
mesh_io.write("triangle_reorder.msh", mesh);
n = mesh.getNbNodes();
partition->partitionate(psize);
communicator = akantu::Communicator::createCommunicatorDistributeMesh(mesh, partition);
delete partition;
} else {
communicator = akantu::Communicator::createCommunicatorDistributeMesh(mesh, NULL);
}
std::cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA " << mesh.getNbGlobalNodes() << std::endl;
akantu::SparseMatrix sparse_matrix(mesh, akantu::_symmetric, 2, "mesh");
sparse_matrix.buildProfile();
akantu::Solver * solver = new akantu::SolverMumps(sparse_matrix);
if(prank == 0) {
for(akantu::UInt i = 0; i < n; ++i) {
solver->getRHS().storage()[i] = 1.;
}
}
akantu::debug::setDebugLevel(akantu::dblDump);
solver->initialize();
std::stringstream sstr; sstr << "profile_" << prank << ".mtx";
sparse_matrix.saveProfile(sstr.str());
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_static_memory/CMakeLists.txt b/test/test_static_memory/CMakeLists.txt
index 7d84dfc79..92d72f5d5 100644
--- a/test/test_static_memory/CMakeLists.txt
+++ b/test/test_static_memory/CMakeLists.txt
@@ -1,33 +1,35 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Fri Sep 03 2010
-# @date last modification: Tue Nov 06 2012
+# @date last modification: Tue Dec 02 2014
#
# @brief configuration for static memory tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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
#
#===============================================================================
register_test(test_static_memory SOURCES test_static_memory.cc PACKAGE core)
diff --git a/test/test_static_memory/test_static_memory.cc b/test/test_static_memory/test_static_memory.cc
index e3cac60f9..f1a05e9bd 100644
--- a/test/test_static_memory/test_static_memory.cc
+++ b/test/test_static_memory/test_static_memory.cc
@@ -1,57 +1,58 @@
/**
* @file test_static_memory.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Sep 03 2010
- * @date last modification: Fri Mar 21 2014
+ * @date creation: Mon Jun 14 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief unit test for the StaticMemory class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_static_memory.hh"
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
akantu::StaticMemory & st_mem = akantu::StaticMemory::getStaticMemory();
akantu::Array<int> & test_int = st_mem.smalloc<int>(0, "test_int", 1000, 3);
test_int.resize(1050);
test_int.resize(2000);
std::cout << st_mem << std::endl;
st_mem.sfree(0, "test_int");
akantu::finalize();
exit(EXIT_SUCCESS);
}
diff --git a/test/test_synchronizer/CMakeLists.txt b/test/test_synchronizer/CMakeLists.txt
index 62bd1f74c..c88172dae 100644
--- a/test/test_synchronizer/CMakeLists.txt
+++ b/test/test_synchronizer/CMakeLists.txt
@@ -1,70 +1,71 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Sun Sep 12 2010
-# @date last modification: Fri Sep 05 2014
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Dec 07 2015
#
# @brief configuration for synchronizer tests
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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_mesh(test_synchronizer_communication_mesh
cube.geo 3 2)
register_test(test_synchronizer_communication
SOURCES test_synchronizer_communication.cc
DEPENDS test_synchronizer_communication_mesh
PACKAGE parallel
)
if(AKANTU_DAMAGE_NON_LOCAL)
add_executable(test_grid_synchronizer_check_neighbors test_grid_synchronizer_check_neighbors.cc)
target_link_libraries(test_grid_synchronizer_check_neighbors akantu)
endif()
register_test(test_grid_synchronizer
SOURCES test_grid_synchronizer.cc test_data_accessor.hh
DEPENDS test_synchronizer_communication_mesh test_grid_synchronizer_check_neighbors
EXTRA_FILES test_grid_synchronizer_check_neighbors.cc test_grid_tools.hh
PACKAGE damage_non_local
)
register_test(test_dof_synchronizer
SOURCES test_dof_synchronizer.cc test_data_accessor.hh
FILES_TO_COPY bar.msh
PACKAGE parallel
)
register_test(test_dof_synchronizer_communication
SOURCES test_dof_synchronizer_communication.cc test_dof_data_accessor.hh
DEPENDS test_synchronizer_communication_mesh
PACKAGE parallel
)
register_test(test_data_distribution
SOURCES test_data_distribution.cc
FILES_TO_COPY data_split.msh
PACKAGE parallel
)
diff --git a/test/test_synchronizer/test_data_accessor.hh b/test/test_synchronizer/test_data_accessor.hh
index 041376bd7..a4c91f1d2 100644
--- a/test/test_synchronizer/test_data_accessor.hh
+++ b/test/test_synchronizer/test_data_accessor.hh
@@ -1,134 +1,134 @@
/**
* @file test_data_accessor.hh
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Thu Apr 11 2013
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Data Accessor class for testing
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "data_accessor.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class TestAccessor : public DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
inline TestAccessor(const Mesh & mesh, const ElementTypeMapArray<Real> & barycenters);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Barycenter, barycenters, Real);
/* ------------------------------------------------------------------------ */
/* Ghost Synchronizer inherited members */
/* ------------------------------------------------------------------------ */
protected:
inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
const ElementTypeMapArray<Real> & barycenters;
const Mesh & mesh;
};
/* -------------------------------------------------------------------------- */
/* TestSynchronizer implementation */
/* -------------------------------------------------------------------------- */
inline TestAccessor::TestAccessor(const Mesh & mesh,
const ElementTypeMapArray<Real> & barycenters)
: barycenters(barycenters), mesh(mesh) { }
inline UInt TestAccessor::getNbDataForElements(const Array<Element> & elements,
__attribute__ ((unused)) SynchronizationTag tag) const {
if(elements.getSize())
// return Mesh::getSpatialDimension(elements(0).type) * sizeof(Real) * elements.getSize();
return mesh.getSpatialDimension() * sizeof(Real) * elements.getSize();
else
return 0;
}
inline void TestAccessor::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
__attribute__ ((unused)) SynchronizationTag tag) const {
UInt spatial_dimension = mesh.getSpatialDimension();
Array<Element>::const_iterator<Element> bit = elements.begin();
Array<Element>::const_iterator<Element> bend = elements.end();
for (; bit != bend; ++bit) {
const Element & element = *bit;
Vector<Real> bary(this->barycenters(element.type, element.ghost_type).storage()
+ element.element * spatial_dimension,
spatial_dimension);
buffer << bary;
}
}
inline void TestAccessor::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
__attribute__ ((unused)) SynchronizationTag tag) {
UInt spatial_dimension = mesh.getSpatialDimension();
Array<Element>::const_iterator<Element> bit = elements.begin();
Array<Element>::const_iterator<Element> bend = elements.end();
for (; bit != bend; ++bit) {
const Element & element = *bit;
Vector<Real> barycenter_loc(this->barycenters(element.type, element.ghost_type).storage()
+ element.element * spatial_dimension,
spatial_dimension);
Vector<Real> bary(spatial_dimension);
buffer >> bary;
std::cout << element << barycenter_loc << std::endl;
Real tolerance = 1e-15;
for (UInt i = 0; i < spatial_dimension; ++i) {
if(!(std::abs(bary(i) - barycenter_loc(i)) <= tolerance))
AKANTU_DEBUG_ERROR("Unpacking an unknown value for the element: "
<< element
<< "(barycenter[" << i << "] = " << barycenter_loc(i)
<< " and buffer[" << i << "] = " << bary(i) << ") - tag: " << tag);
}
}
}
__END_AKANTU__
diff --git a/test/test_synchronizer/test_data_distribution.cc b/test/test_synchronizer/test_data_distribution.cc
index 286ed5bff..a348e25db 100644
--- a/test/test_synchronizer/test_data_distribution.cc
+++ b/test/test_synchronizer/test_data_distribution.cc
@@ -1,200 +1,200 @@
/**
* @file test_data_distribution.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Sep 05 2014
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test the mesh distribution on creation of a distributed synchonizer
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "distributed_synchronizer.hh"
#include "mesh_partition_mesh_data.hh"
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
Mesh mesh_group_after (spatial_dimension, "after");
Mesh mesh_group_before(spatial_dimension, "before");
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
DistributedSynchronizer *communicator_a, *communicator_b;
if(prank == 0) {
mesh_group_before.read("data_split.msh");
mesh_group_after .read("data_split.msh");
mesh_group_before.createGroupsFromMeshData<std::string>("physical_names");
mesh_group_before.registerData<UInt>("global_id");
mesh_group_after. registerData<UInt>("global_id");
for (Mesh::type_iterator tit = mesh_group_after.firstType(_all_dimensions); tit != mesh_group_after.lastType(_all_dimensions); ++tit) {
Array<UInt> & gidb = *(mesh_group_before.getDataPointer<UInt>("global_id", *tit));
Array<UInt> & gida = *(mesh_group_after .getDataPointer<UInt>("global_id", *tit));
Array<UInt>::scalar_iterator ait = gida.begin();
Array<UInt>::scalar_iterator bit = gidb.begin();
Array<UInt>::scalar_iterator end = gida.end();
for (UInt i = 0; ait != end; ++ait, ++i, ++bit) {
*bit = i;
*ait = i;
}
}
MeshPartitionScotch * partition = new MeshPartitionScotch(mesh_group_after, spatial_dimension);
partition->partitionate(psize);
communicator_a = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh_group_after , partition);
communicator_b = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh_group_before, partition);
delete partition;
} else {
communicator_a = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh_group_after , NULL);
communicator_b = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh_group_before, NULL);
}
mesh_group_after.createGroupsFromMeshData<std::string>("physical_names");
if(prank == 0) std::cout << mesh_group_after;
GroupManager::element_group_iterator grp_ait = mesh_group_after.element_group_begin();
GroupManager::element_group_iterator grp_end = mesh_group_after.element_group_end();
for (; grp_ait != grp_end; ++grp_ait) {
std::string grp = grp_ait->first;
const ElementGroup & bgrp = mesh_group_before.getElementGroup(grp);
const ElementGroup & agrp = *grp_ait->second;
for (ghost_type_t::iterator git = ghost_type_t::begin(); git != ghost_type_t::end(); ++git) {
GhostType ghost_type = *git;
for (Mesh::type_iterator tit = bgrp.firstType(_all_dimensions, ghost_type);
tit != bgrp.lastType(_all_dimensions, ghost_type); ++tit) {
Array<UInt> & gidb = *(mesh_group_before.getDataPointer<UInt>("global_id", *tit, ghost_type));
Array<UInt> & gida = *(mesh_group_after .getDataPointer<UInt>("global_id", *tit, ghost_type));
Array<UInt> bgelem(bgrp.getElements(*tit, ghost_type));
Array<UInt> agelem(agrp.getElements(*tit, ghost_type));
Array<UInt>::scalar_iterator ait = agelem.begin();
Array<UInt>::scalar_iterator bit = bgelem.begin();
Array<UInt>::scalar_iterator end = agelem.end();
for (; ait != end; ++ait, ++bit) {
*bit = gidb(*bit);
*ait = gida(*ait);
}
std::sort(bgelem.begin(), bgelem.end());
std::sort(agelem.begin(), agelem.end());
if(!std::equal(bgelem.begin(), bgelem.end(), agelem.begin())) {
std::cerr << "The filters array for the group " << grp <<
" and for the element type " << *tit << ", " << ghost_type <<
" do not match" <<std::endl;
debug::setDebugLevel(dblTest);
std::cerr << bgelem << std::endl;
std::cerr << agelem << std::endl;
debug::debugger.exit(EXIT_FAILURE);
}
}
}
}
GroupManager::node_group_iterator ngrp_ait = mesh_group_after.node_group_begin();
GroupManager::node_group_iterator ngrp_end = mesh_group_after.node_group_end();
for (; ngrp_ait != ngrp_end; ++ngrp_ait) {
std::string grp = ngrp_ait->first;
const NodeGroup & bgrp = mesh_group_before.getNodeGroup(grp);
const NodeGroup & agrp = *ngrp_ait->second;
const Array<UInt> & gidb = mesh_group_before.getGlobalNodesIds();
const Array<UInt> & gida = mesh_group_after.getGlobalNodesIds();
Array<UInt> bgnode(0, 1);
Array<UInt> agnode(0, 1);
Array<UInt>::const_scalar_iterator ait = agrp.begin();
Array<UInt>::const_scalar_iterator bit = bgrp.begin();
Array<UInt>::const_scalar_iterator end = agrp.end();
for (; ait != end; ++ait, ++bit) {
if(psize > 1) {
if(mesh_group_before.isLocalOrMasterNode(*bit))
bgnode.push_back(gidb(*bit));
if(mesh_group_after.isLocalOrMasterNode(*ait))
agnode.push_back(gida(*ait));
}
}
std::sort(bgnode.begin(), bgnode.end());
std::sort(agnode.begin(), agnode.end());
if(!std::equal(bgnode.begin(), bgnode.end(), agnode.begin())) {
std::cerr << "The filters array for the group " << grp <<
" do not match" <<std::endl;
debug::setDebugLevel(dblTest);
std::cerr << bgnode << std::endl;
std::cerr << agnode << std::endl;
debug::debugger.exit(EXIT_FAILURE);
}
}
mesh_group_after.getElementGroup("inside").setBaseName("after_inside");
mesh_group_after.getElementGroup("inside").dump();
mesh_group_after.getElementGroup("outside").setBaseName("after_outside");
mesh_group_after.getElementGroup("outside").dump();
mesh_group_after.getElementGroup("volume").setBaseName("after_volume");
mesh_group_after.getElementGroup("volume").dump();
mesh_group_before.getElementGroup("inside").setBaseName("before_inside");
mesh_group_before.getElementGroup("inside").dump();
mesh_group_before.getElementGroup("outside").setBaseName("before_outside");
mesh_group_before.getElementGroup("outside").dump();
mesh_group_before.getElementGroup("volume").setBaseName("before_volume");
mesh_group_before.getElementGroup("volume").dump();
delete communicator_a;
delete communicator_b;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_synchronizer/test_dof_data_accessor.hh b/test/test_synchronizer/test_dof_data_accessor.hh
index 9288d4360..c1c4f6055 100644
--- a/test/test_synchronizer/test_dof_data_accessor.hh
+++ b/test/test_synchronizer/test_dof_data_accessor.hh
@@ -1,115 +1,117 @@
/**
* @file test_dof_data_accessor.hh
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Thu Nov 20 11:01:28 2014
*
- * @brief data accessor class for testing the
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Tue Dec 09 2014
+ *
+ * @brief data accessor class for testing the
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "data_accessor.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class TestDOFAccessor : public DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
inline TestDOFAccessor(const Array<Int> & global_dof_equation_numbers);
/* ------------------------------------------------------------------------ */
/* Ghost Synchronizer inherited members */
/* ------------------------------------------------------------------------ */
protected:
inline UInt getNbDataForDOFs(const Array<UInt> & dofs,
SynchronizationTag tag) const;
inline void packDOFData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
SynchronizationTag tag) const;
inline void unpackDOFData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
const Array<Int> & global_dof_equation_numbers;
};
/* -------------------------------------------------------------------------- */
/* TestDOFSynchronizer implementation */
/* -------------------------------------------------------------------------- */
inline TestDOFAccessor::TestDOFAccessor(const Array<Int> & global_dof_equation_numbers)
: global_dof_equation_numbers(global_dof_equation_numbers) { }
inline UInt TestDOFAccessor::getNbDataForDOFs(const Array<UInt> & dofs,
__attribute__ ((unused)) SynchronizationTag tag) const {
if(dofs.getSize())
// return Mesh::getSpatialDimension(elements(0).type) * sizeof(Real) * elements.getSize();
return sizeof(Int) * dofs.getSize();
else
return 0;
}
inline void TestDOFAccessor::packDOFData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
__attribute__ ((unused)) SynchronizationTag tag) const {
Array<UInt>::const_scalar_iterator bit = dofs.begin();
Array<UInt>::const_scalar_iterator bend = dofs.end();
for (; bit != bend; ++bit) {
buffer << this->global_dof_equation_numbers[*bit];
}
}
inline void TestDOFAccessor::unpackDOFData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
__attribute__ ((unused)) SynchronizationTag tag) {
Array<UInt>::const_scalar_iterator bit = dofs.begin();
Array<UInt>::const_scalar_iterator bend = dofs.end();
for (; bit != bend; ++bit) {
Int global_dof_eq_nb_local = global_dof_equation_numbers[*bit];
Int global_dof_eq_nb = 0;
buffer >> global_dof_eq_nb;
std::cout << *bit << global_dof_eq_nb_local << std::endl;
Real tolerance = Math::getTolerance();
if(!(std::abs(global_dof_eq_nb - global_dof_eq_nb_local) <= tolerance))
AKANTU_DEBUG_ERROR("Unpacking an unknown value for the dof: "
<< *bit
<< "(global_dof_equation_number = " << global_dof_eq_nb_local
<< " and buffer = " << global_dof_eq_nb << ") - tag: " << tag);
}
}
__END_AKANTU__
diff --git a/test/test_synchronizer/test_dof_synchronizer.cc b/test/test_synchronizer/test_dof_synchronizer.cc
index 9bf6f7914..d16ba6086 100644
--- a/test/test_synchronizer/test_dof_synchronizer.cc
+++ b/test/test_synchronizer/test_dof_synchronizer.cc
@@ -1,230 +1,231 @@
/**
* @file test_dof_synchronizer.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
- * @date last modification: Thu Apr 03 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Test the functionality of the DOFSynchronizer class
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "dof_synchronizer.hh"
#include "mesh_partition_scotch.hh"
#include "mesh_io.hh"
#include "static_communicator.hh"
#include "distributed_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
# include "io_helper.hh"
#endif //AKANTU_USE_IOHELPER
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char *argv[])
{
const UInt spatial_dimension = 2;
initialize(argc, argv);
StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
Mesh mesh(spatial_dimension);
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
DistributedSynchronizer * communicator;
MeshPartition * partition;
if(prank == 0) {
MeshIOMSH mesh_io;
mesh_io.read("bar.msh", mesh);
std::cout << "Partitioning mesh..." << std::endl;
partition = new akantu::MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
UInt nb_nodes = mesh.getNbNodes();
Array<Real> dof_vector(nb_nodes, spatial_dimension, "Test vector");
std::cout << "Initializing the synchronizer" << std::endl;
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
/* ------------------------------------------------------------------------ */
/* test the sznchroniyation */
/* ------------------------------------------------------------------------ */
for (UInt n = 0; n < nb_nodes; ++n) {
UInt gn = mesh.getNodeGlobalId(n);
for (UInt d = 0; d < spatial_dimension; ++d) {
if(mesh.isMasterNode(n)) dof_vector(n,d) = gn*spatial_dimension + d;
else if(mesh.isLocalNode(n)) dof_vector(n,d) = - (double) (gn*spatial_dimension + d);
else if(mesh.isSlaveNode(n)) dof_vector(n,d) = NAN;
else dof_vector(n,d) = -NAN;
}
}
std::cout << "Synchronizing a dof vector" << std::endl;
dof_synchronizer.synchronize(dof_vector);
for (UInt n = 0; n < nb_nodes; ++n) {
UInt gn = mesh.getNodeGlobalId(n);
for (UInt d = 0; d < spatial_dimension; ++d) {
if(!((mesh.isMasterNode(n) && dof_vector(n,d) == (gn*spatial_dimension + d)) ||
(mesh.isLocalNode(n) && dof_vector(n,d) == - (double) (gn*spatial_dimension + d)) ||
(mesh.isSlaveNode(n) && dof_vector(n,d) == (gn*spatial_dimension + d)) ||
(mesh.isPureGhostNode(n))
)
)
{
debug::setDebugLevel(dblTest);
std::cout << "prank : " << prank << " (node " << gn*spatial_dimension + d << "[" << n * spatial_dimension + d << "]) - "
<< (mesh.isMasterNode(n) && dof_vector(n,d) == (gn*spatial_dimension + d)) << " "
<< (mesh.isLocalNode(n) && dof_vector(n,d) == - (double) (gn*spatial_dimension + d)) << " "
<< (mesh.isSlaveNode(n) && dof_vector(n,d) == (gn*spatial_dimension + d)) << " "
<< (mesh.isPureGhostNode(n)) << std::endl;
std::cout << dof_vector << dof_synchronizer.getDOFGlobalIDs() << dof_synchronizer.getDOFTypes() << std::endl;
debug::setDebugLevel(dblDebug);
return EXIT_FAILURE;
}
}
}
/* ------------------------------------------------------------------------ */
/* test the reduce operation */
/* ------------------------------------------------------------------------ */
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt d = 0; d < spatial_dimension; ++d) {
if(mesh.isMasterNode(n)) dof_vector(n,d) = 1;
else if(mesh.isLocalNode(n)) dof_vector(n,d) = -300;
else if(mesh.isSlaveNode(n)) dof_vector(n,d) = 2;
else dof_vector(n,d) = -500;
}
}
std::cout << "Reducing a dof vector" << std::endl;
dof_synchronizer.reduceSynchronize<AddOperation>(dof_vector);
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt d = 0; d < spatial_dimension; ++d) {
if(!((mesh.isMasterNode(n) && dof_vector(n,d) >= 3) ||
(mesh.isLocalNode(n) && dof_vector(n,d) == -300) ||
(mesh.isSlaveNode(n) && dof_vector(n,d) >= 3) ||
(mesh.isPureGhostNode(n) && dof_vector(n,d) == -500)
)
)
{
debug::setDebugLevel(dblTest);
std::cout << dof_vector
<< dof_synchronizer.getDOFGlobalIDs()
<< dof_synchronizer.getDOFTypes() << std::endl;
debug::setDebugLevel(dblDebug);
return EXIT_FAILURE;
}
}
}
/* ------------------------------------------------------------------------ */
/* test the gather/scatter */
/* ------------------------------------------------------------------------ */
dof_vector.clear();
for (UInt n = 0; n < nb_nodes; ++n) {
UInt gn = mesh.getNodeGlobalId(n);
for (UInt d = 0; d < spatial_dimension; ++d) {
if(mesh.isMasterNode(n)) dof_vector(n,d) = gn * spatial_dimension + d;
else if(mesh.isLocalNode(n)) dof_vector(n,d) = - (double) (gn * spatial_dimension + d);
else if(mesh.isSlaveNode(n)) dof_vector(n,d) = NAN;
else dof_vector(n,d) = -NAN;
}
}
std::cout << "Initializing the gather/scatter information" << std::endl;
dof_synchronizer.initScatterGatherCommunicationScheme();
std::cout << "Gathering on proc 0" << std::endl;
if(prank == 0) {
UInt nb_global_nodes = mesh.getNbGlobalNodes();
Array<Real> gathered(nb_global_nodes, spatial_dimension, "gathered information");
dof_synchronizer.gather(dof_vector, 0, &gathered);
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt d = 0; d < spatial_dimension; ++d) {
if(std::abs(gathered(n,d)) != n * spatial_dimension + d) {
debug::setDebugLevel(dblTest);
std::cout << gathered << std::endl;
std::cout << dof_vector
<< dof_synchronizer.getDOFGlobalIDs()
<< dof_synchronizer.getDOFTypes() << std::endl;
debug::setDebugLevel(dblDebug);
return EXIT_FAILURE;
}
}
}
} else {
dof_synchronizer.gather(dof_vector, 0);
}
dof_vector.clear();
std::cout << "Scattering from proc 0" << std::endl;
if(prank == 0) {
UInt nb_global_nodes = mesh.getNbGlobalNodes();
Array<Real> to_scatter(nb_global_nodes, spatial_dimension, "to scatter information");
for (UInt d = 0; d < nb_global_nodes * spatial_dimension; ++d) {
to_scatter.storage()[d] = d;
}
dof_synchronizer.scatter(dof_vector, 0, &to_scatter);
} else {
dof_synchronizer.scatter(dof_vector, 0);
}
for (UInt n = 0; n < nb_nodes; ++n) {
UInt gn = mesh.getNodeGlobalId(n);
for (UInt d = 0; d < spatial_dimension; ++d) {
if(!mesh.isPureGhostNode(n) && !(dof_vector(n,d) == (gn * spatial_dimension + d))) {
debug::setDebugLevel(dblTest);
std::cout << dof_vector
<< dof_synchronizer.getDOFGlobalIDs()
<< dof_synchronizer.getDOFTypes() << std::endl;
debug::setDebugLevel(dblDebug);
return EXIT_FAILURE;
}
}
}
delete communicator;
finalize();
return 0;
}
diff --git a/test/test_synchronizer/test_dof_synchronizer_communication.cc b/test/test_synchronizer/test_dof_synchronizer_communication.cc
index b1eb23333..bcd700aef 100644
--- a/test/test_synchronizer/test_dof_synchronizer_communication.cc
+++ b/test/test_synchronizer/test_dof_synchronizer_communication.cc
@@ -1,100 +1,102 @@
/**
* @file test_dof_synchronizer_communication.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Thu Nov 20 13:40:33 2014
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Tue Dec 09 2014
*
* @brief test to synchronize global equation numbers
*
* @section LICENSE
*
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "distributed_synchronizer.hh"
#include "dof_synchronizer.hh"
#include "synchronizer_registry.hh"
#include "mesh.hh"
#include "mesh_partition_scotch.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
#endif //AKANTU_USE_IOHELPER
#include "test_dof_data_accessor.hh"
using namespace akantu;
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
initialize(argc, argv);
UInt spatial_dimension = 3;
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
bool wait=true;
if(argc >1) {
if(prank == 0)
while(wait);
}
DistributedSynchronizer * communicator = NULL;
if(prank == 0) {
mesh.read("cube.msh");
MeshPartition * partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
/* -------------------------------------------------------------------------- */
/* test the communications of the dof synchronizer */
/* -------------------------------------------------------------------------- */
std::cout << "Initializing the synchronizer" << std::endl;
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
dof_synchronizer.initGlobalDOFEquationNumbers();
AKANTU_DEBUG_INFO("Creating TestDOFAccessor");
TestDOFAccessor test_dof_accessor(dof_synchronizer.getGlobalDOFEquationNumbers());
SynchronizerRegistry synch_registry(test_dof_accessor);
synch_registry.registerSynchronizer(dof_synchronizer,_gst_test);
AKANTU_DEBUG_INFO("Synchronizing tag");
synch_registry.synchronize(_gst_test);
delete communicator;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_synchronizer/test_grid_synchronizer.cc b/test/test_synchronizer/test_grid_synchronizer.cc
index 5563f76ea..babdcd7a1 100644
--- a/test/test_synchronizer/test_grid_synchronizer.cc
+++ b/test/test_synchronizer/test_grid_synchronizer.cc
@@ -1,297 +1,298 @@
/**
* @file test_grid_synchronizer.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri Nov 25 2011
- * @date last modification: Tue Jun 24 2014
+ * @date creation: Wed Sep 01 2010
+ * @date last modification: Fri Feb 27 2015
*
* @brief test the GridSynchronizer object
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "aka_grid_dynamic.hh"
#include "mesh.hh"
#include "grid_synchronizer.hh"
#include "mesh_partition.hh"
#include "synchronizer_registry.hh"
#include "test_data_accessor.hh"
#ifdef AKANTU_USE_IOHELPER
# include "io_helper.hh"
#endif //AKANTU_USE_IOHELPER
using namespace akantu;
const UInt spatial_dimension = 3;
typedef std::map<std::pair<Element, Element>, Real> pair_list;
#include "test_grid_tools.hh"
static void updatePairList(const ElementTypeMapArray<Real> & barycenter,
const SpatialGrid<Element> & grid,
Real radius,
pair_list & neighbors,
neighbors_map_t<spatial_dimension>::type & neighbors_map) {
AKANTU_DEBUG_IN();
GhostType ghost_type = _not_ghost;
Element e;
e.ghost_type = ghost_type;
// generate the pair of neighbor depending of the cell_list
ElementTypeMapArray<Real>::type_iterator it = barycenter.firstType(_all_dimensions, ghost_type);
ElementTypeMapArray<Real>::type_iterator last_type = barycenter.lastType(0, ghost_type);
for(; it != last_type; ++it) {
// loop over quad points
e.type = *it;
e.element = 0;
const Array<Real> & barycenter_vect = barycenter(*it, ghost_type);
UInt sp = barycenter_vect.getNbComponent();
Array<Real>::const_iterator< Vector<Real> > bary =
barycenter_vect.begin(sp);
Array<Real>::const_iterator< Vector<Real> > bary_end =
barycenter_vect.end(sp);
for(;bary != bary_end; ++bary, e.element++) {
#if !defined(AKANTU_NDEBUG)
Point<spatial_dimension> pt1(*bary);
#endif
SpatialGrid<Element>::CellID cell_id = grid.getCellID(*bary);
SpatialGrid<Element>::neighbor_cells_iterator first_neigh_cell =
grid.beginNeighborCells(cell_id);
SpatialGrid<Element>::neighbor_cells_iterator last_neigh_cell =
grid.endNeighborCells(cell_id);
// loop over neighbors cells of the one containing the current element
for (; first_neigh_cell != last_neigh_cell; ++first_neigh_cell) {
SpatialGrid<Element>::Cell::const_iterator first_neigh_el =
grid.beginCell(*first_neigh_cell);
SpatialGrid<Element>::Cell::const_iterator last_neigh_el =
grid.endCell(*first_neigh_cell);
// loop over the quadrature point in the current cell of the cell list
for (;first_neigh_el != last_neigh_el; ++first_neigh_el){
const Element & elem = *first_neigh_el;
Array<Real>::const_iterator< Vector<Real> > neigh_it =
barycenter(elem.type, elem.ghost_type).begin(sp);
const Vector<Real> & neigh_bary = neigh_it[elem.element];
Real distance = bary->distance(neigh_bary);
if(distance <= radius) {
#if !defined(AKANTU_NDEBUG)
Point<spatial_dimension> pt2(neigh_bary);
neighbors_map[pt1].push_back(pt2);
#endif
std::pair<Element, Element> pair = std::make_pair(e, elem);
pair_list::iterator p = neighbors.find(pair);
if(p != neighbors.end()) {
AKANTU_DEBUG_ERROR("Pair already registered [" << e << " " << elem << "] -> " << p->second << " " << distance);
} else {
neighbors[pair] = distance;
}
}
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
akantu::initialize(argc, argv);
Real radius = 0.001;
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
DistributedSynchronizer * dist = NULL;
if(prank == 0) {
mesh.read("bar.msh");
MeshPartition * partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
dist = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
dist = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
mesh.computeBoundingBox();
const Vector<Real> & lower_bounds = mesh.getLowerBounds();
const Vector<Real> & upper_bounds = mesh.getUpperBounds();
Vector<Real> center = 0.5 * (upper_bounds + lower_bounds);
Vector<Real> spacing(spatial_dimension);
for (UInt i = 0; i < spatial_dimension; ++i) {
spacing[i] = radius * 1.2;
}
SpatialGrid<Element> grid(spatial_dimension, spacing, center);
GhostType ghost_type = _not_ghost;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
ElementTypeMapArray<Real> barycenters("", "");
mesh.initElementTypeMapArray(barycenters, spatial_dimension, spatial_dimension);
Element e;
e.ghost_type = ghost_type;
for(; it != last_type; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
e.type = *it;
Array<Real> & barycenter = barycenters(*it, ghost_type);
barycenter.resize(nb_element);
Array<Real>::iterator< Vector<Real> > bary_it = barycenter.begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem) {
mesh.getBarycenter(elem, *it, bary_it->storage(), ghost_type);
e.element = elem;
grid.insert(e, *bary_it);
++bary_it;
}
}
std::stringstream sstr; sstr << "mesh_" << prank << ".msh";
mesh.write(sstr.str());
Mesh grid_mesh(spatial_dimension, "grid_mesh", 0);
std::stringstream sstr_grid; sstr_grid << "grid_mesh_" << prank << ".msh";
grid.saveAsMesh(grid_mesh);
grid_mesh.write(sstr_grid.str());
std::cout << "Pouet 1" << std::endl;
AKANTU_DEBUG_INFO("Creating TestAccessor");
TestAccessor test_accessor(mesh, barycenters);
SynchronizerRegistry synch_registry(test_accessor);
GridSynchronizer * grid_communicator = GridSynchronizer::createGridSynchronizer(mesh, grid);
std::cout << "Pouet 2" << std::endl;
ghost_type = _ghost;
it = mesh.firstType(spatial_dimension, ghost_type);
last_type = mesh.lastType(spatial_dimension, ghost_type);
e.ghost_type = ghost_type;
for(; it != last_type; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
e.type = *it;
Array<Real> & barycenter = barycenters(*it, ghost_type);
barycenter.resize(nb_element);
Array<Real>::iterator< Vector<Real> > bary_it = barycenter.begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem) {
mesh.getBarycenter(elem, *it, bary_it->storage(), ghost_type);
e.element = elem;
grid.insert(e, *bary_it);
++bary_it;
}
}
Mesh grid_mesh_ghost(spatial_dimension, "grid_mesh_ghost", 0);
std::stringstream sstr_gridg; sstr_gridg << "grid_mesh_ghost_" << prank << ".msh";
grid.saveAsMesh(grid_mesh_ghost);
grid_mesh_ghost.write(sstr_gridg.str());
std::cout << "Pouet 3" << std::endl;
neighbors_map_t<spatial_dimension>::type neighbors_map;
pair_list neighbors;
updatePairList(barycenters, grid, radius, neighbors, neighbors_map);
pair_list::iterator nit = neighbors.begin();
pair_list::iterator nend = neighbors.end();
std::stringstream sstrp; sstrp << "pairs_" << prank;
std::ofstream fout(sstrp.str().c_str());
for(;nit != nend; ++nit) {
fout << "[" << nit->first.first << "," << nit->first.second << "] -> "
<< nit->second << std::endl;
}
std::string file = "neighbors_ref";
std::stringstream sstrf; sstrf << file << "_" << prank;
file = sstrf.str();
std::ofstream nout;
nout.open(file.c_str());
neighbors_map_t<spatial_dimension>::type::iterator it_n = neighbors_map.begin();
neighbors_map_t<spatial_dimension>::type::iterator end_n = neighbors_map.end();
for(;it_n != end_n; ++it_n) {
std::sort(it_n->second.begin(), it_n->second.end());
std::vector< Point<spatial_dimension> >::iterator it_v = it_n->second.begin();
std::vector< Point<spatial_dimension> >::iterator end_v = it_n->second.end();
nout << "####" << std::endl;
nout << it_n->second.size() << std::endl;
nout << it_n->first << std::endl;
nout << "#" << std::endl;
for(;it_v != end_v; ++it_v) {
nout << *it_v << std::endl;
}
}
fout.close();
synch_registry.registerSynchronizer(*dist, _gst_smm_mass);
synch_registry.registerSynchronizer(*grid_communicator, _gst_test);
AKANTU_DEBUG_INFO("Synchronizing tag on Dist");
synch_registry.synchronize(_gst_smm_mass);
AKANTU_DEBUG_INFO("Synchronizing tag on Grid");
synch_registry.synchronize(_gst_test);
delete grid_communicator;
delete dist;
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc b/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc
index 685623463..d7ca9bb56 100644
--- a/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc
+++ b/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc
@@ -1,122 +1,122 @@
/**
* @file test_grid_synchronizer_check_neighbors.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Mar 11 2013
- * @date last modification: Mon Jan 20 2014
+ * @date last modification: Fri Feb 27 2015
*
* @brief Test the generation of neighbors list based on a akaentu::Grid
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <fstream>
#include <iostream>
#include <string>
#include "aka_common.hh"
#include "static_communicator.hh"
using namespace akantu;
const UInt spatial_dimension = 3;
#include "test_grid_tools.hh"
void readNeighbors(std::ifstream & nin,
neighbors_map_t<spatial_dimension>::type & neighbors_map_read) {
std::string line;
while (std::getline(nin, line)) {
std::getline(nin, line);
std::istringstream iss(line);
UInt nb_neig;
iss >> nb_neig;
std::getline(nin, line);
Point<spatial_dimension> pt;
pt.read(line);
std::getline(nin, line);
for (UInt i = 0; i < nb_neig; ++i) {
std::getline(nin, line);
Point<spatial_dimension> ne;
ne.read(line);
neighbors_map_read[pt].push_back(ne);
}
}
}
int main(int argc, char *argv[]) {
initialize(argc, argv);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
// Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
std::string file_ref = "neighbors_ref";
std::string file = file_ref;
std::stringstream sstr; sstr << file << "_" << prank;
file = sstr.str();
std::ifstream nin;
neighbors_map_t<spatial_dimension>::type neighbors_map_read;
nin.open(file_ref.c_str());
readNeighbors(nin, neighbors_map_read);
nin.close();
neighbors_map_t<spatial_dimension>::type neighbors_map;
nin.open(file.c_str());
readNeighbors(nin, neighbors_map);
nin.close();
neighbors_map_t<spatial_dimension>::type::iterator it_n = neighbors_map.begin();
neighbors_map_t<spatial_dimension>::type::iterator end_n = neighbors_map.end();
for(;it_n != end_n; ++it_n) {
std::sort(it_n->second.begin(), it_n->second.end());
std::vector< Point<spatial_dimension> >::iterator it_v = it_n->second.begin();
std::vector< Point<spatial_dimension> >::iterator end_v = it_n->second.end();
neighbors_map_t<spatial_dimension>::type::iterator it_nr = neighbors_map_read.find(it_n->first);
if(it_nr == neighbors_map_read.end())
AKANTU_DEBUG_ERROR("Argh what is this point that is not present in the ref file " << it_n->first);
std::vector< Point<spatial_dimension> >::iterator it_vr = it_nr->second.begin();
std::vector< Point<spatial_dimension> >::iterator end_vr = it_nr->second.end();
for(;it_v != end_v && it_vr != end_vr; ++it_v, ++it_vr) {
if(*it_vr != *it_v) AKANTU_DEBUG_ERROR("Neighbors does not match " << *it_v << " != " << *it_vr
<< " neighbor of " << it_n->first);
}
if(it_v == end_v && it_vr != end_vr) {
AKANTU_DEBUG_ERROR("Some neighbors of " << it_n->first << " are missing!");
}
if(it_v != end_v && it_vr == end_vr)
AKANTU_DEBUG_ERROR("Some neighbors of " << it_n->first << " are in excess!");
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_synchronizer/test_grid_tools.hh b/test/test_synchronizer/test_grid_tools.hh
index a74dead2f..e7c9b34ea 100644
--- a/test/test_synchronizer/test_grid_tools.hh
+++ b/test/test_synchronizer/test_grid_tools.hh
@@ -1,109 +1,109 @@
/**
* @file test_grid_tools.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Mar 11 2013
- * @date last modification: Wed Nov 13 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Tools to help for the akantu::Grid class tests
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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 <http://www.gnu.org/licenses/>.
*
*/
#include <map>
#include "aka_common.hh"
#include "aka_types.hh"
#define TOLERANCE 1e-7
template<UInt dim>
class Point {
public:
Point() : id(0), tol(TOLERANCE) {
for (UInt i = 0; i < dim; ++i) pos[i] = 0.;
}
Point(const Point & pt) : id(pt.id), tol(pt.tol) {
for (UInt i = 0; i < dim; ++i) pos[i] = pt.pos[i];
}
Point(const Vector<Real> & pt, UInt id = 0) : id(id), tol(TOLERANCE) {
for (UInt i = 0; i < dim; ++i) pos[i] = pt(i);
}
bool operator==(const Point & pt) const {
for (UInt i = 0; i < dim; ++i) {
// std::cout << i << " " << pos[i] << " " << pt.pos[i] << " " << std::abs(pos[i] - pt.pos[i]);
if (std::abs(pos[i] - pt.pos[i]) > tol) {
// std::cout << " " << false << std::endl;
return false;
} //else
// std::cout << " " << true << std::endl;
}
return true;
}
bool operator<(const Point & pt) const {
UInt i = 0, j = 0;
for ( ; (i < dim) && (j < dim); i++, j++ ) {
if (pos[i] < pt.pos[j]) return true;
if (pt.pos[j] < pos[i]) return false;
}
return (i == dim) && (j != dim);
}
bool operator!=(const Point & pt) const {
return !(operator==(pt));
}
Real & operator()(UInt d) { return pos[d]; }
const Real & operator()(UInt d) const { return pos[d]; }
void read(const std::string & str) {
std::stringstream sstr(str);
for (UInt i = 0; i < dim; ++i) sstr >> pos[i];
}
void write(std::ostream & ostr) const {
for (UInt i = 0; i < dim; ++i) {
if(i != 0) ostr << " ";
// ostr << std::setprecision(std::numeric_limits<Real>::digits) << pos[i];
ostr << std::setprecision(9) << pos[i];
}
}
private:
UInt id;
Real pos[dim];
double tol;
};
template<UInt dim>
struct neighbors_map_t {
typedef std::map<Point<dim>, std::vector< Point<dim> > > type;
};
template<UInt dim>
inline std::ostream & operator <<(std::ostream & stream, const Point<dim> & _this)
{
_this.write(stream);
return stream;
}
diff --git a/test/test_synchronizer/test_synchronizer_communication.cc b/test/test_synchronizer/test_synchronizer_communication.cc
index 200c258eb..64b901b2e 100644
--- a/test/test_synchronizer/test_synchronizer_communication.cc
+++ b/test/test_synchronizer/test_synchronizer_communication.cc
@@ -1,158 +1,159 @@
/**
* @file test_synchronizer_communication.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Sun Sep 12 2010
- * @date last modification: Tue Jun 24 2014
+ * @date creation: Wed Sep 01 2010
+ * @date last modification: Sun Oct 19 2014
*
* @brief test to synchronize barycenters
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 "aka_common.hh"
#include "distributed_synchronizer.hh"
#include "synchronizer_registry.hh"
#include "mesh.hh"
#include "mesh_partition_scotch.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
#endif //AKANTU_USE_IOHELPER
#include "test_data_accessor.hh"
using namespace akantu;
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
initialize(argc, argv);
UInt spatial_dimension = 3;
Mesh mesh(spatial_dimension);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
bool wait=true;
if(argc >1) {
if(prank == 0)
while(wait);
}
DistributedSynchronizer * communicator;
if(prank == 0) {
mesh.read("cube.msh");
MeshPartition * partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
/// compute barycenter for each facet
ElementTypeMapArray<Real> barycenters("barycenters", "", 0);
mesh.initElementTypeMapArray(barycenters, spatial_dimension, spatial_dimension);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
ghost_type);
for(; it != last_type; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
Array<Real> & barycenter = barycenters(*it, ghost_type);
barycenter.resize(nb_element);
Array<Real>::iterator< Vector<Real> > bary_it
= barycenter.begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem, ++bary_it)
mesh.getBarycenter(elem, *it, bary_it->storage(), ghost_type);
}
}
AKANTU_DEBUG_INFO("Creating TestAccessor");
TestAccessor test_accessor(mesh, barycenters);
SynchronizerRegistry synch_registry(test_accessor);
synch_registry.registerSynchronizer(*communicator,_gst_test);
AKANTU_DEBUG_INFO("Synchronizing tag");
synch_registry.synchronize(_gst_test);
// Checking the tags in MeshData (not a very good test because they're all identical,
// but still...)
Mesh::type_iterator it = mesh.firstType(_all_dimensions);
Mesh::type_iterator last_type = mesh.lastType(_all_dimensions);
for (; it != last_type; ++it) {
Array<UInt> & tags = mesh.getData<UInt>("tag_0", *it);
Array<UInt>::const_vector_iterator tags_it = tags.begin(1);
Array<UInt>::const_vector_iterator tags_end = tags.end(1);
AKANTU_DEBUG_ASSERT(mesh.getNbElement(*it) == tags.getSize(),
"The number of tags does not match the number of elements on rank " << prank << ".");
std::cout << std::dec << " I am rank " << prank << " and here's my MeshData dump for types "
<< *it << " (it should contain " << mesh.getNbElement(*it)
<< " elements and it has " << tags.getSize() << "!) :" << std::endl;
std::cout << std::hex;
debug::setDebugLevel(dblTest);
for(; tags_it != tags_end; ++tags_it) {
std::cout << tags_it->operator()(0) << " ";
//AKANTU_DEBUG_ASSERT(*tags_it == 1, "The tag does not match the expected value on rank " << prank << " (got " << *tags_it << " instead.");
}
debug::setDebugLevel(dblInfo);
std::cout << std::endl;
}
// #ifdef AKANTU_USE_IOHELPER
// DumperParaview dumper("test-scotch-partition");
// dumper.registerMesh(mesh, spatial_dimension, _not_ghost);
// dumper.registerField("partitions",
// new DumperIOHelper::ElementPartitionField<>(mesh, spatial_dimension, _not_ghost));
// dumper.dump();
// DumperParaview dumper_ghost("test-scotch-partition-ghost");
// dumper_ghost.registerMesh(mesh, spatial_dimension, _ghost);
// dumper_ghost.registerField("partitions",
// new DumperIOHelper::ElementPartitionField<>(mesh, spatial_dimension, _ghost));
// dumper_ghost.dump();
// #endif //AKANTU_USE_IOHELPER
delete communicator;
finalize();
return EXIT_SUCCESS;
}
diff --git a/third-party/cmake/blackdynamite.cmake b/third-party/cmake/blackdynamite.cmake
index e37bcdaa6..67a9d9a79 100644
--- a/third-party/cmake/blackdynamite.cmake
+++ b/third-party/cmake/blackdynamite.cmake
@@ -1,41 +1,71 @@
+#===============================================================================
+# @file blackdynamite.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Wed Jun 10 2015
+# @date last modification: Mon Sep 28 2015
+#
+# @brief build script for blackdynamite
+#
+# @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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
if(${PROJECT_SOURCE_DIR}/third-party/${BLACKDYNAMITE_ARCHIVE})
set(_blackdynamite_download_command
URL ${PROJECT_SOURCE_DIR}/third-party/${BLACKDYNAMITE_ARCHIVE})
else()
set(_blackdynamite_download_command
GIT_REPOSITORY ${BLACKDYNAMITE_GIT}
GIT_TAG ${BLACKDYNAMITE_VERSION}
)
endif()
if(CMAKE_VERSION VERSION_GREATER 3.1)
set(_extra_options
UPDATE_DISCONNECTED 1
DOWNLOAD_NO_PROGRESS 1
EXCLUDE_FROM_ALL 1
)
endif()
ExternalProject_Add(blackdynamite
PREFIX ${PROJECT_BINARY_DIR}/third-party
${_blackdynamite_download_command}
${_extra_options}
CMAKE_ARGS <SOURCE_DIR>/
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER}
BUILD_COMMAND make
INSTALL_COMMAND make install
LOG_DOWNLOAD 1
LOG_CONFIGURE 1
LOG_BUILD 1
LOG_INSTALL 1
)
set_third_party_shared_libirary_name(BLACKDYNAMITE_LIBRARIES blackdynamite)
set(BLACKDYNAMITE_INCLUDE_DIR "${PROJECT_BINARY_DIR}/third-party/include/blackdynamite" CACHE PATH "")
mark_as_advanced(
BLACKDYNAMITE_LIBRARIES
BLACKDYNAMITE_INCLUDE_DIR
)
package_add_extra_dependency(BlackDynamite blackdynamite)
diff --git a/third-party/cmake/blas.cmake b/third-party/cmake/blas.cmake
index 62288c4f3..600d86c96 100644
--- a/third-party/cmake/blas.cmake
+++ b/third-party/cmake/blas.cmake
@@ -1,24 +1,54 @@
+#===============================================================================
+# @file blas.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Wed Nov 11 2015
+# @date last modification: Wed Nov 11 2015
+#
+# @brief build script for netlib-blas
+#
+# @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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
set(BLAS_DIR ${PROJECT_BINARY_DIR}/third-party)
configure_file(
${PROJECT_SOURCE_DIR}/third-party/blas_${BLAS_VERSION}_make.inc.cmake
${BLAS_DIR}/blas_make.inc @ONLY)
file(MAKE_DIRECTORY ${BLAS_DIR}/lib)
ExternalProject_Add(netlib-blas
PREFIX ${BLAS_DIR}
URL ${BLAS_ARCHIVE}
CONFIGURE_COMMAND cmake -E copy ${BLAS_DIR}/blas_make.inc make.inc
BUILD_IN_SOURCE 1
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SHARED_LIBRARY_PREFIX}blas${CMAKE_SHARED_LIBRARY_SUFFIX} <INSTALL_DIR>/lib
LOG_DOWNLOAD 1
LOG_CONFIGURE 1
LOG_BUILD 1
LOG_INSTALL 1
)
package_add_extra_dependency(BLAS netlib-blas)
set_third_party_shared_libirary_name(BLAS_LIBRARIES blas)
diff --git a/third-party/cmake/iohelper.cmake b/third-party/cmake/iohelper.cmake
index 507973371..330ef2836 100644
--- a/third-party/cmake/iohelper.cmake
+++ b/third-party/cmake/iohelper.cmake
@@ -1,45 +1,75 @@
+#===============================================================================
+# @file iohelper.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Mar 30 2015
+# @date last modification: Wed Nov 11 2015
+#
+# @brief build script for iohelper
+#
+# @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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/third-party/${IOHELPER_ARCHIVE})
set(_iohelper_download_command
GIT_REPOSITORY ${IOHELPER_GIT}
GIT_TAG ${IOHELPER_VERSION}
)
else()
set(_iohelper_download_command
URL ${PROJECT_SOURCE_DIR}/third-party/${IOHELPER_ARCHIVE}
)
endif()
if(CMAKE_VERSION VERSION_GREATER 3.1)
set(_extra_options
UPDATE_DISCONNECTED 1
DOWNLOAD_NO_PROGRESS 1
EXCLUDE_FROM_ALL 1
)
endif()
ExternalProject_Add(iohelper
PREFIX ${PROJECT_BINARY_DIR}/third-party
${_iohelper_download_command}
${_extra_options}
CMAKE_ARGS <SOURCE_DIR>/
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER}
LOG_DOWNLOAD 1
LOG_CONFIGURE 1
LOG_BUILD 1
LOG_INSTALL 1
)
set_third_party_shared_libirary_name(IOHELPER_LIBRARIES iohelper)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(_tmp ${IOHELPER_LIBRARIES})
set(IOHELPER_LIBRARIES "${_tmp}.a" CACHE FILEPATH "" FORCE)
endif()
set(IOHELPER_INCLUDE_DIR "${PROJECT_BINARY_DIR}/third-party/include/iohelper" CACHE PATH "IOHelper include directory")
mark_as_advanced(
IOHELPER_LIBRARIES
IOHELPER_INCLUDE_DIR
)
package_add_extra_dependency(IOHelper iohelper)
diff --git a/third-party/cmake/mumps.cmake b/third-party/cmake/mumps.cmake
index 2153aa534..8a2387e7a 100644
--- a/third-party/cmake/mumps.cmake
+++ b/third-party/cmake/mumps.cmake
@@ -1,152 +1,152 @@
#===============================================================================
# @file mumps.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Nov 21 2011
-# @date last modification: Mon Sep 15 2014
+# @date creation: Mon Mar 30 2015
+# @date last modification: Wed Nov 11 2015
#
# @brief compilation of the third-party MUMPS
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
enable_language(Fortran)
set(MUMPS_VERSION ${AKANTU_USE_MUMPS_VERSION})
set(MUMPS_ARCHIVE "${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}.tar.gz")
set(MUMPS_ARCHIVE_HASH_4.9.2 "MD5=d0b8f139a4acf29b76dbae69ade8ac54")
set(MUMPS_ARCHIVE_HASH_4.10.0 "MD5=959e9981b606cd574f713b8422ef0d9f")
set(MUMPS_ARCHIVE_HASH_5.0.0 "MD5=3c6aeab847e9d775ca160194a9db2b75")
if(NOT EXISTS ${MUMPS_ARCHIVE})
message(FATAL_ERROR "To be able to compile MUMPS please download it from "
"http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS and place it "
"in the directory: ${PROJECT_SOURCE_DIR}/third-party and in cmake set the "
"variable AKANTU_MUMPS_VERSION to the corresponding version "
"\n"
"Supported version for automated compilation in Akantu are 4.9.2, 4.10.0 "
"and 5.0.0")
endif()
package_get_option_name(MPI _mpi_option)
if(${_mpi_option})
unset(MUMPS_PREFIX)
else()
set(MUMPS_PREFIX _seq)
endif()
package_use_system(Scotch _scotch_use_system)
if(NOT _scotch_use_system)
list(APPEND MUMPS_DEPENDS Scotch)
endif()
package_get_option_name(ScaLAPACK _scalapack_option)
package_use_system(ScaLAPACK _scalapack_use_system)
if(NOT _scalapack_use_system AND ${_scalapack_option})
list(APPEND MUMPS_DEPENDS ScaLAPACK)
endif()
include(AkantuMacros)
package_get_libraries(Scotch _scotch_libraries)
string(REPLACE ";" " " MUMPS_SCOTCH_LIBRARIES
"${_scotch_libraries};${SCOTCH_LIBRARY_ESMUMPS}")
package_get_libraries(BLAS _blas_libraries)
foreach(_blas_lib ${_blas_libraries})
if("${_blas_lib}" MATCHES ".*\\.framework")
get_filename_component(_blas_framework "${_blas_lib}" NAME_WE)
set(MUMPS_BLAS_LIBRARIES "${MUMPS_BLAS_LIBRARIES} -framework ${_blas_framework}")
else()
set(MUMPS_BLAS_LIBRARIES "${MUMPS_BLAS_LIBRARIES} ${_blas_lib}")
endif()
endforeach()
if("${MUMPS_TYPE}" STREQUAL "seq")
set_third_party_shared_libirary_name(MUMPS_LIBRARY_MPI mpiseq${MUMPS_PREFIX})
mark_as_advanced(MUMPS_LIBRARY_MPI)
else()
set(MUMPS_LIBRARY_MPI "")
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "Intel")
set(MUMPS_EXTRA_Fortran_FLAGS "-nofor_main")
else()
set(MUMPS_EXTRA_Fortran_FLAGS "")
endif()
if(CMAKE_VERSION VERSION_GREATER 3.1)
set(_extra_options
DOWNLOAD_NO_PROGRESS 1
EXCLUDE_FROM_ALL 1
)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(AKANTU_MUMPS_CDEFS "-DAdd_ -DWITHOUT_PTHREAD")
else()
set(AKANTU_MUMPS_CDEFS "-DAdd_")
set(AKANTU_MUMPS_PTHREAD "-lpthread")
endif()
configure_file(${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}_make.inc.cmake
${PROJECT_BINARY_DIR}/third-party/MUMPS_make.inc @ONLY)
ExternalProject_Add(MUMPS
DEPENDS ${MUMPS_DEPENDS}
PREFIX ${PROJECT_BINARY_DIR}/third-party
URL ${MUMPS_ARCHIVE}
URL_HASH ${MUMPS_ARCHIVE_HASH_${MUMPS_VERSION}}
${_extra_options}
BUILD_IN_SOURCE 1
PATCH_COMMAND ${PATCH_COMMAND} -p2 < ${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}.patch
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/third-party/MUMPS_make.inc Makefile.inc
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} d
INSTALL_COMMAND "${CMAKE_MAKE_PROGRAM}" prefix=<INSTALL_DIR> install
LOG_DOWNLOAD 1
LOG_CONFIGURE 1
LOG_BUILD 1
LOG_INSTALL 1
)
set_third_party_shared_libirary_name(MUMPS_LIBRARY_DMUMPS dmumps${MUMPS_PREFIX})
set_third_party_shared_libirary_name(MUMPS_LIBRARY_COMMON mumps_common${MUMPS_PREFIX})
set_third_party_shared_libirary_name(MUMPS_LIBRARY_PORD pord${MUMPS_PREFIX})
mark_as_advanced(
MUMPS_LIBRARY_COMMON
MUMPS_LIBRARY_DMUMPS
MUMPS_LIBRARY_PORD
MUMPS_LIBRARY_MPI
MUMPS_INCLUDE_DIR
)
set(MUMPS_LIBRARIES_ALL
${MPI_Fortran_LIBRARIES}
${MUMPS_LIBRARY_COMMON}
${MUMPS_LIBRARY_DMUMPS}
${MUMPS_LIBRARY_PORD}
${MUMPS_LIBRARY_MPI})
set(MUMPS_INCLUDE_DIR ${PROJECT_BINARY_DIR}/third-party/include CACHE PATH "" FORCE)
set(MUMPS_LIBRARIES ${MUMPS_LIBRARIES_ALL} CACHE INTERNAL "Libraries for MUMPS" FORCE)
package_add_extra_dependency(Mumps MUMPS)
diff --git a/third-party/cmake/scalapack.cmake b/third-party/cmake/scalapack.cmake
index 0ad66a21f..be7626c4e 100644
--- a/third-party/cmake/scalapack.cmake
+++ b/third-party/cmake/scalapack.cmake
@@ -1,69 +1,69 @@
#===============================================================================
# @file scalapack.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Mon Nov 21 2011
-# @date last modification: Mon Sep 15 2014
+# @date creation: Mon Mar 30 2015
+# @date last modification: Wed Jun 10 2015
#
# @brief package description for mumps support
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# 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 <http://www.gnu.org/licenses/>.
#
#===============================================================================
enable_language(Fortran)
if(CMAKE_VERSION VERSION_GREATER 3.1)
set(_extra_options
UPDATE_DISCONNECTED 1
DOWNLOAD_NO_PROGRESS 1
EXCLUDE_FROM_ALL 1
)
endif()
set(SCALAPACK_DIR ${PROJECT_BINARY_DIR}/third-party)
ExternalProject_Add(ScaLAPACK
PREFIX ${SCALAPACK_DIR}
URL ${SCALAPACK_ARCHIVE}
URL_HASH ${SCALAPACK_ARCHIVE_HASH}
${_extra_options}
PATCH_COMMAND patch -p1 < ${PROJECT_SOURCE_DIR}/third-party/scalapack_${SCALAPACK_VERSION}.patch
CMAKE_COMMAND BLA_VENDOR=$ENV{BLA_VENDOR} MPICH_F90=${CMAKE_Fortran_COMPILER} ${CMAKE_COMMAND}
CMAKE_ARGS <SOURCE_DIR>/ScaLAPACK
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DMPIEXEC:PATH=${MPIEXEC}
-DCMAKE_C_COMPILER:PATH=${CMAKE_C_COMPILER}
-DMPI_C_COMPILER:PATH=${MPI_C_COMPILER}
-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}
-DCMAKE_Fortran_COMPILER:PATH=${CMAKE_Fortran_COMPILER}
-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}
-DMPI_Fortran_COMPILER:PATH=${MPI_Fortran_COMPILER}
-DBUILD_SHARED_LIBS:BOOL=ON
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
BUILD_COMMAND BLA_VENDOR=$ENV{BLA_VENDOR} MPICH_F90=${CMAKE_Fortran_COMPILER} ${CMAKE_MAKE_PROGRAM}
LOG_DOWNLOAD 1
LOG_CONFIGURE 1
LOG_BUILD 1
LOG_INSTALL 1
)
set_third_party_shared_libirary_name(SCALAPACK_LIBRARIES scalapack)
set(SCALAPACK_INCLUDE_DIR ${SCALAPACK_DIR}/include CACHE PATH "" FORCE)
mark_as_advanced(SCALAPACK_LIBRARIES SCALAPACK_INCLUDE_DIR)
diff --git a/third-party/cmake/scotch.cmake b/third-party/cmake/scotch.cmake
index 31e9ddc1e..fe9f5e7ff 100644
--- a/third-party/cmake/scotch.cmake
+++ b/third-party/cmake/scotch.cmake
@@ -1,98 +1,128 @@
+#===============================================================================
+# @file scotch.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Mar 30 2015
+# @date last modification: Wed Nov 11 2015
+#
+# @brief build script 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 <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
if(TARGET Scotch)
return()
endif()
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/third-party/${SCOTCH_ARCHIVE})
set(_scotch_download_command
URL ${SCOTCH_URL}
# URL_HASH ${SCOTCH_ARCHIVE_HASH}
TLS_VERIFY FALSE
)
else()
set(_scotch_download_command
URL ${PROJECT_SOURCE_DIR}/third-party/${SCOTCH_ARCHIVE}
URL_HASH ${SCOTCH_ARCHIVE_HASH})
endif()
if(CMAKE_VERSION VERSION_GREATER 3.1)
set(_extra_options
DOWNLOAD_NO_PROGRESS 1
EXCLUDE_FROM_ALL 1
)
endif()
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
find_package(ZLIB)
#if(ZLIB_FOUND)
# set(_zlib_cflags "-DCOMMON_FILE_COMPRESS_GZ -I${ZLIB_INCLUDE_DIR}")
# set(_zlib_ldflags "${ZLIB_LIBRARY}")
#endif()
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
if (AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
set(_timing_cflags -DCOMMON_TIMING_OLD)
endif()
set(_system_cflags "-DCOMMON_PTHREAD -DSCOTCH_PTHREAD ${_timing_cflags}")
set(_system_ldflags "-lpthread")
else()
set(_system_cflags "-DCOMMON_RANDOM_RAND -DCOMMON_WINDOWS -DCOMMON_STUB_FORK -D'pipe(pfds)=_pipe(pfds,1024,0x8000)'")
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_architecture_cflags -DIDXSIZE64)
endif()
math(EXPR _n "${AKANTU_INTEGER_SIZE} * 8")
if(NOT _n EQUAL 32)
set(_num_size_cflags "-DINTSIZE${_n}")
endif()
if(HAVE_STDINT_H)
set(_stdint -DHAVE_STDINT_H)
endif()
set(AKANTU_SCOTCH_CFLAGS "-O3 -w -fPIC -Drestrict=__restrict -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_RENAME_PARSER ${_zlib_cflags} ${_system_cflags} ${_architecture_cflags} ${_num_size_cflags} ${_stdint}")
set(AKANTU_SCOTCH_LDFLAGS "${_zlib_ldflags} ${_system_ldflags} -lm")
set(SCOTCH_DIR ${PROJECT_BINARY_DIR}/third-party)
configure_file(
${PROJECT_SOURCE_DIR}/third-party/scotch_${SCOTCH_VERSION}_make.inc.cmake
${SCOTCH_DIR}/scotch_make.inc)
include(ExternalProject)
ExternalProject_Add(Scotch
PREFIX ${SCOTCH_DIR}
${_scotch_download_command}
${_extra_options}
PATCH_COMMAND ${PATCH_COMMAND} -p1 < ${PROJECT_SOURCE_DIR}/third-party/scotch_${SCOTCH_VERSION}.patch
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy ${SCOTCH_DIR}/scotch_make.inc src/Makefile.inc
BUILD_IN_SOURCE 1
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} -C src
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} prefix=<INSTALL_DIR> -C src install
LOG_DOWNLOAD 1
LOG_CONFIGURE 1
LOG_BUILD 1
LOG_INSTALL 1
)
set_third_party_shared_libirary_name(SCOTCH_LIBRARY scotch)
set_third_party_shared_libirary_name(SCOTCH_LIBRARY_ERR scotcherr)
set_third_party_shared_libirary_name(SCOTCH_LIBRARY_ERREXIT scotcherrexit)
set_third_party_shared_libirary_name(SCOTCH_LIBRARY_ESMUMPS esmumps)
set(SCOTCH_INCLUDE_DIR ${SCOTCH_DIR}/include CACHE PATH "" FORCE)
mark_as_advanced(
SCOTCH_LIBRARY
SCOTCH_LIBRARY_ERR
SCOTCH_LIBRARY_ERREXIT
SCOTCH_LIBRARY_ESMUMPS
SCOTCH_INCLUDE_DIR)
set(SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY} ${SCOTCH_LIBRARY_ERR})
set(SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES_ALL} CACHE INTERNAL "Libraries for scotch" FORCE)
package_add_extra_dependency(Scotch Scotch)

Event Timeline